Merge pull request #475 from winterheart/cfile-std-filesystem

cfile / ddio: use most of functions to std::filesystem::path
This commit is contained in:
Louis Gombert 2024-07-06 23:25:12 +00:00 committed by GitHub
commit de75a80ae7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
47 changed files with 921 additions and 1129 deletions

View File

@ -636,6 +636,11 @@
*
* $NoKeywords: $
*/
#include <cstring>
#include <cstdlib>
#include <filesystem>
#include "Mission.h"
#include "3d.h"
#include "LoadLevel.h"
@ -665,8 +670,6 @@
#include "osiris_dll.h"
#include "mission_download.h"
#include "manage.h"
#include <string.h>
#include <stdlib.h>
#include "ship.h"
#include "BOA.h"
#include "terrain.h"
@ -742,10 +745,10 @@ void InitMission() {
Current_mission.mn3_handle = 0;
// create add on mission directory
ddio_MakePath(D3MissionsDir, LocalD3Dir, "missions", NULL);
if (!ddio_DirExists(D3MissionsDir)) {
if (!ddio_CreateDir(D3MissionsDir)) {
Error(TXT_MSN_FAILEDCREATEDIR);
}
std::error_code ec;
std::filesystem::create_directories(D3MissionsDir, ec);
if (ec) {
Error(TXT_MSN_FAILEDCREATEDIR);
}
atexit(ResetMission);
}

View File

@ -75,21 +75,17 @@ void SetMovieProperties(int x, int y, int w, int h, renderer_type type) {
mve_SetRenderProperties(x, y, w, h, type, kHiColorEnabled);
}
bool PlayMovie(const char *moviename) {
bool PlayMovie(const std::filesystem::path &moviename) {
if (!Cinematic_lib_init)
return false;
// get in the right directory
char filename[_MAX_PATH];
strncpy(filename, moviename, sizeof(filename) - 1);
filename[sizeof(filename) - 1] = 0;
std::filesystem::path filename = moviename;
// check extension
const char *extension = strrchr(filename, '.');
if (extension == NULL || (stricmp(extension, ".mve") != 0 && stricmp(extension, ".mv8") != 0)) {
std::filesystem::path extension = moviename.extension();
if (stricmp(extension.u8string().c_str(), ".mve") != 0 && stricmp(extension.u8string().c_str(), ".mv8") != 0) {
// we need an extension
strncat(filename, ".mve", sizeof(filename) - strlen(filename) - 1);
filename[sizeof(filename) - 1] = 0;
filename.replace_extension(extension.u8string() + ".mve");
}
// shutdown sound.
@ -110,7 +106,7 @@ bool PlayMovie(const char *moviename) {
SetMovieProperties(0, 0, Max_window_w, Max_window_h, Renderer_type);
int mveerr = mve_PlayMovie(filename, Descent);
int mveerr = mve_PlayMovie(filename.u8string().c_str(), Descent);
// Shutdown the subtitle system
SubtCloseSubtitles();

View File

@ -1,5 +1,5 @@
/*
* Descent 3
* Descent 3
* Copyright (C) 2024 Parallax Software
*
* This program is free software: you can redistribute it and/or modify
@ -55,6 +55,7 @@
#include "bitmap.h"
#include <cstdint>
#include <filesystem>
// Movie Cinematic
struct tCinematic {
@ -65,7 +66,7 @@ struct tCinematic {
bool InitCinematics();
void SetMovieProperties(int x, int y, int w, int h, renderer_type type);
bool PlayMovie(const char *moviename);
bool PlayMovie(const std::filesystem::path &moviename);
tCinematic *StartMovie(const char *moviename, bool looping = false);
bool FrameMovie(tCinematic *mve, int x, int y, bool sequence = true);
void EndMovie(tCinematic *mve);

View File

@ -383,6 +383,7 @@
#include <algorithm>
#include <cstdlib>
#include <filesystem>
#include <vector>
#include "pserror.h"
@ -483,15 +484,14 @@ void Descent3() {
// Show the intro movie
if (!FindArg("-nointro")) {
char intropath[_MAX_PATH * 2];
// Intros to be played
const std::vector<const char *> intros = {
const std::vector<std::filesystem::path> intros = {
"dolby1.mv8",
"intro.mve",
};
for (auto const &intro : intros) {
ddio_MakePath(intropath, Base_directory, "movies", intro, nullptr);
std::filesystem::path intropath = std::filesystem::path(Base_directory) / "movies" / intro;
if (cfexist(intropath)) {
PlayMovie(intropath);
}

View File

@ -263,6 +263,9 @@
* $NoKeywords: $
*/
#include <cstring>
#include <filesystem>
#include "gamesave.h"
#include "descent.h"
#include "newui.h"
@ -291,7 +294,6 @@
#include "osiris_dll.h"
#include "levelgoal.h"
#include "aistruct.h"
#include <string.h>
#include "matcen.h"
#include "hud.h"
#include "marker.h"
@ -395,11 +397,10 @@ void SaveGameDialog() {
// ddio_MakePath(pathname, savegame_dir, "*.sav", NULL); -unused
// create savegame directory if it didn't exist before.
if (!ddio_DirExists(savegame_dir)) {
if (!ddio_CreateDir(savegame_dir)) {
DoMessageBox(TXT_ERROR, TXT_ERRCREATEDIR, MSGBOX_OK);
return;
}
std::error_code ec;
if (!std::filesystem::create_directories(savegame_dir, ec)) {
DoMessageBox(TXT_ERROR, TXT_ERRCREATEDIR, MSGBOX_OK);
return;
}
// open window
@ -589,7 +590,7 @@ bool LoadGameDialog() {
ddio_MakePath(pathname, savegame_dir, "*.sav", NULL);
// create savegame directory if it didn't exist before.
if (!ddio_DirExists(savegame_dir)) {
if (!std::filesystem::is_directory(savegame_dir)) {
DoMessageBox(TXT_ERROR, TXT_ERRNOSAVEGAMES, MSGBOX_OK);
return false;
}

View File

@ -594,9 +594,9 @@ int menutga_alloc_file(const char *name, char *hsmap[1], int *w, int *h) {
// TODO: MTS: only used in this file
// Given a filename and a hotspotmap structure, it saves it to disk (.HSM)
void menutga_SaveHotSpotMap(const char *filename, hotspotmap_t *hsmap, windowmap_t *wndmap) {
void menutga_SaveHotSpotMap(const std::filesystem::path &filename, hotspotmap_t *hsmap, windowmap_t *wndmap) {
CFILE *file;
mprintf(0, "Saving HotSpotMap %s ", filename);
mprintf(0, "Saving HotSpotMap %s ", filename.u8string().c_str());
file = (CFILE *)cfopen(filename, "wb");
if (!file) {
Int3(); // get jeff!
@ -883,7 +883,7 @@ bool menutga_ConvertTGAtoHSM(const char *fpath) {
strcat(menu_filename, ".HSM"); // Hot Spot Map
mprintf(0, "HSM=%s\n", menu_filename);
ddio_MakePath(path, LocalManageGraphicsDir, menu_filename, NULL);
std::filesystem::path save_path = LocalManageGraphicsDir / menu_filename;
// now load up the tga and alloc it, then save it with the alpha hotspots
int bm_handle;
@ -895,7 +895,7 @@ bool menutga_ConvertTGAtoHSM(const char *fpath) {
if (wndmap.num_of_windows == -1)
return false; // DAJ -1FIX
CreateWindowMap(map[0], width, height, &wndmap);
menutga_SaveHotSpotMap(path, &hsmap, &wndmap);
menutga_SaveHotSpotMap(save_path, &hsmap, &wndmap);
ExportHotSpot("C:\\hotspot.txt", &hsmap);
mem_free(menu_filename);
mem_free(map[0]);

View File

@ -48,6 +48,7 @@
#ifndef __HOTSPOTMAP_H_
#define __HOTSPOTMAP_H_
#include <filesystem>
#include "grdefs.h"
// for the next two defines this is how they work when converting the alpha values into hotspots/windows
@ -99,7 +100,7 @@ struct windowmap_t {
// Loads a tga or ogf file into a bitmap...returns handle to bm or -1 on error, and fills in the alphamap
int menutga_alloc_file(const char *name, char *hsmap[], int *w, int *h);
// Given a filename and a HotSpotMap structure, it saves it to disk (.HSM)
void menutga_SaveHotSpotMap(const char *filename, hotspotmap_t *hsmap, windowmap_t *wndmap);
void menutga_SaveHotSpotMap(const std::filesystem::path &filename, hotspotmap_t *hsmap, windowmap_t *wndmap);
// Given a filename and a HotSpotMap structure, it loads the hotspot map (.HSM)
void menutga_LoadHotSpotMap(int back_bmp, const char *filename, hotspotmap_t *hsmap, windowmap_t *wndmap);
// This function (given a filename) loads a TGA file, extracts a hotspot map, and saves the hotspot map

View File

@ -100,6 +100,11 @@
*
* $NoKeywords: $
*/
#include <cstdlib>
#include <cstring>
#include <filesystem>
#include "mono.h"
#include "renderer.h"
#include "render.h"
@ -108,8 +113,6 @@
#include "game.h"
#include "cfile.h"
#include "application.h"
#include <stdlib.h>
#include <string.h>
#include "newui.h"
#include "grtext.h"
#include "gamefont.h"
@ -311,7 +314,7 @@ bool DoPathFileDialog(bool save_dialog, char *path, const char *title, const cha
if (path[0] == '\0') {
DoMessageBox(TXT_ERROR, TXT_ERRCHOOSEFILE, MSGBOX_OK);
} else {
if (ddio_DirExists(path)) {
if (std::filesystem::is_directory(path)) {
char newpath[_MAX_PATH];
char file[_MAX_PATH];
int selection = listbox->GetCurrentIndex();
@ -424,7 +427,7 @@ bool DoPathFileDialog(bool save_dialog, char *path, const char *title, const cha
strcpy(c, edits[ED_FILENAME]);
if (strlen(c) > 0) {
if (!ddio_DirExists(c)) {
if (!std::filesystem::is_directory(c)) {
// the user wants a file
if (flags & PFDF_FILEMUSTEXIST) {
if (cfexist(c)) {
@ -500,7 +503,7 @@ int GetFilesInPath(char **buffer, int maxcount, const char *p, const char *wildc
char tempbuffer[_MAX_PATH];
if (ddio_FindFileStart(wildcard, tempbuffer)) {
if (!ddio_DirExists(tempbuffer)) {
if (!std::filesystem::is_directory(tempbuffer)) {
buffer[count] = mem_strdup(tempbuffer);
count++;
}
@ -509,7 +512,7 @@ int GetFilesInPath(char **buffer, int maxcount, const char *p, const char *wildc
while (!done) {
if (ddio_FindNextFile(tempbuffer)) {
if (!ddio_DirExists(tempbuffer)) {
if (!std::filesystem::is_directory(tempbuffer)) {
if (count < maxcount)
buffer[count] = mem_strdup(tempbuffer);
count++;
@ -559,7 +562,7 @@ int GetDirectoriesInPath(char **buffer, int maxcount, const char *p) {
char tempbuffer[_MAX_PATH];
if (ddio_FindFileStart("*", tempbuffer)) {
if (ddio_DirExists(tempbuffer)) {
if (std::filesystem::is_directory(tempbuffer)) {
buffer[count] = mem_strdup(tempbuffer);
count++;
}
@ -568,7 +571,7 @@ int GetDirectoriesInPath(char **buffer, int maxcount, const char *p) {
while (!done) {
if (ddio_FindNextFile(tempbuffer)) {
if (ddio_DirExists(tempbuffer)) {
if (std::filesystem::is_directory(tempbuffer)) {
if (count < maxcount)
buffer[count] = mem_strdup(tempbuffer);
count++;

View File

@ -217,44 +217,23 @@ void SubtResetSubTitles(void) {
}
// Initializes the subtitles for a given movie file
void SubtInitSubtitles(const char *filename) {
void SubtInitSubtitles(const std::filesystem::path &filename) {
// Load the subtitles
Num_subtitles = 0;
Movie_subtitle_init = 0;
CFILE *ifile;
char subtitle_file[_MAX_FNAME], subtitle_path[_MAX_PATH], *p;
// need a quick out here if no subtitles.
if (!FindArg("-subtitles"))
return;
// find the start of the filename
const char *pFilenameStart = strrchr(filename, '\\');
if (pFilenameStart != NULL) {
filename = pFilenameStart + 1;
}
std::filesystem::path subtitle_path = std::filesystem::path(LocalArtDir) / "movies" / filename;
subtitle_path.replace_extension(MOVIE_SUBTITLE_EXTENSION);
pFilenameStart = strrchr(filename, '/');
if (pFilenameStart != NULL) {
filename = pFilenameStart + 1;
}
mprintf(0, "Looking for the subtitle file %s\n", subtitle_path.u8string().c_str());
// strip off any extension for the movie and append the subtitle text
strcpy(subtitle_file, filename);
p = strchr(subtitle_file, '.');
if (p) {
*p = '\0';
}
strcat(subtitle_file, MOVIE_SUBTITLE_EXTENSION);
ddio_MakePath(subtitle_path, LocalD3Dir, "movies", subtitle_file, NULL);
mprintf(0, "Looking for the subtitle file %s\n", subtitle_path);
ifile = cfopen(subtitle_path, "rt");
CFILE *ifile = cfopen(subtitle_path, "rt");
if (!ifile) {
mprintf(0, "Movie: Couldn't find subtitle file %s\n", subtitle_path);
mprintf(0, "Movie: Couldn't find subtitle file %s\n", subtitle_path.u8string().c_str());
return;
}

View File

@ -35,11 +35,13 @@
#ifndef __SUBTITLES_H_
#define __SUBTITLES_H_
#include <filesystem>
// draw the subtitles for this frame
void SubtDrawSubtitles(int frame_num);
// Shutsdown the subtitle system
void SubtCloseSubtitles();
// Initializes the subtitles for a given movie file
void SubtInitSubtitles(const char *filename);
void SubtInitSubtitles(const std::filesystem::path &filename);
#endif

View File

@ -154,8 +154,11 @@
* $NoKeywords: $
*/
#include <stdlib.h>
#include <string.h>
#include <cctype>
#include <cstdlib>
#include <cstring>
#include <filesystem>
#include "pstypes.h"
#include "pserror.h"
#include "bitmap.h"
@ -164,9 +167,6 @@
#include "mono.h"
#include "ddio.h"
#include "gametexture.h"
#include "texture.h"
#include <string.h>
#include "ctype.h"
#include "mem.h"
#include "game.h"
@ -239,18 +239,18 @@ void FreeVClip(int num) {
// Saves a given video clip to a file
// Returns 1 if everything ok, 0 otherwise
// "num" is index into GameVClip array
int SaveVClip(const char *filename, int num) {
int SaveVClip(const std::filesystem::path& filename, int num) {
CFILE *outfile;
vclip *vc = &GameVClips[num];
ASSERT(vc->used);
ASSERT(filename != NULL);
ASSERT(!filename.empty());
PageInVClip(num);
outfile = (CFILE *)cfopen(filename, "wb");
if (!outfile) {
mprintf(0, "Couldn't save vclip %s!\n", filename);
mprintf(0, "Couldn't save vclip %s!\n", filename.u8string().c_str());
return 0;
}
@ -267,7 +267,7 @@ int SaveVClip(const char *filename, int num) {
// Now save each frame of this vclip
for (int i = 0; i < vc->num_frames; i++) {
if (bm_SaveBitmap(outfile, vc->frames[i]) != 1) {
mprintf(0, "Couldn't save frame %d of vclip %s!\n", i, filename);
mprintf(0, "Couldn't save frame %d of vclip %s!\n", i, filename.u8string().c_str());
Int3();
cfclose(outfile);
return 0;

View File

@ -20,7 +20,8 @@
#define VCLIP_H
#include "pstypes.h"
#include <filesystem>
#include "fix.h"
#include "manage.h"
@ -56,7 +57,7 @@ void FreeVClip(int num);
// Saves a given video clip to a file
// Returns 1 if everything ok, 0 otherwise
// "num" is index into GameVClip array
int SaveVClip(const char *filename, int num);
int SaveVClip(const std::filesystem::path& filename, int num);
// Allocs and loads a vclip from the file named "filename"
// Returns -1 on error, index into GameVClip array on success

View File

@ -297,9 +297,13 @@
*
* $NoKeywords: $
*/
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <filesystem>
#include "cfile.h"
#include "texture.h"
#include "bitmap.h"
@ -313,10 +317,6 @@
#include "mem.h"
#include "psrand.h"
#include "Macros.h"
#include <algorithm>
#define BM_FILETYPE_TGA 1
#define BM_FILETYPE_PCX 2
#define BM_FILETYPE_IFF 3
@ -1080,7 +1080,7 @@ int bm_MakeBitmapResident(int handle) {
}
// Saves a bitmap to a file. Saves the bitmap as an OUTRAGE_COMPRESSED_OGF.
// Returns -1 if something is wrong.
int bm_SaveFileBitmap(const char *filename, int handle) {
int bm_SaveFileBitmap(const std::filesystem::path& filename, int handle) {
int ret;
CFILE *fp;
if (!GameBitmaps[handle].used) {

View File

@ -15,3 +15,7 @@ target_include_directories(cfile PUBLIC
${PROJECT_SOURCE_DIR}/cfile
>
)
if(BUILD_TESTING)
add_subdirectory(tests)
endif()

View File

@ -16,14 +16,18 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cstdarg>
#include <cerrno>
#include <cctype>
#include <filesystem>
#include <map>
#include <memory>
#include <vector>
#ifndef __LINUX__
// Non-Linux Build Includes
#include <io.h>
@ -50,7 +54,7 @@ struct library_entry {
};
struct library {
char name[_MAX_PATH]; // includes path + filename
std::filesystem::path name; // includes path + filename
uint32_t nfiles = 0;
std::vector<std::unique_ptr<library_entry>> entries;
std::shared_ptr<library> next;
@ -58,25 +62,12 @@ struct library {
FILE *file = nullptr; // pointer to file for this lib, if no one using it
};
// entry in extension->path table
struct ext_entry {
char ext[_MAX_EXT];
uint8_t pathnum;
};
// Map of paths. If value of entry is true, path is only for specific extensions
std::map<std::filesystem::path, bool> paths;
// entry in list of paths
struct path_entry {
char path[_MAX_PATH];
uint8_t specific; // if non-zero, only for specific extensions
};
// Map of extensions <=> relevant paths
std::map<std::filesystem::path, std::filesystem::path> extensions;
#define MAX_PATHS 100
path_entry paths[MAX_PATHS];
int N_paths = 0;
#define MAX_EXTENSIONS 100
ext_entry extensions[MAX_EXTENSIONS];
int N_extensions;
std::shared_ptr<library> Libraries;
int lib_handle = 0;
@ -103,42 +94,36 @@ static CFILE *open_file_in_lib(const char *filename);
// NOTE: libname must be valid for the entire execution of the program. Therefore, it should either
// be a fully-specified path name, or the current directory must not change.
// Returns: 0 if error, else library handle that can be used to close the library
int cf_OpenLibrary(const char *libname) {
int cf_OpenLibrary(const std::filesystem::path &libname) {
FILE *fp;
int i;
uint32_t offset;
static int first_time = 1;
tHogHeader header;
tHogFileEntry entry;
tHogHeader header{};
tHogFileEntry entry{};
// allocation library structure
std::shared_ptr<library> lib = std::make_shared<library>();
#ifdef __LINUX__
// resolve library name
char t_dir[_MAX_PATH];
char t_file[_MAX_PATH];
char t_ext[256];
ddio_SplitPath(libname, t_dir, t_file, t_ext);
const char *resolve_dir = nullptr;
const char *resolve_name = libname;
if (strlen(t_dir) > 0) {
strcat(t_file, t_ext);
resolve_dir = t_dir;
resolve_name = t_file;
std::filesystem::path resolve_dir = libname.parent_path();
std::filesystem::path resolve_name = libname;
if (!resolve_dir.empty()) {
resolve_name = libname.filename();
}
char t_out[_MAX_PATH];
if (!cf_FindRealFileNameCaseInsenstive(resolve_dir, resolve_name, t_out)) {
std::filesystem::path t_out = cf_FindRealFileNameCaseInsensitive(resolve_name, resolve_dir);
if (t_out.empty()) {
return 0; // CF_NO_FILE
}
// re-assemble
if (resolve_dir != nullptr)
ddio_MakePath(lib->name, resolve_dir, t_out, nullptr);
if (!resolve_dir.empty())
lib->name = resolve_dir / t_out;
else
strcpy(lib->name, t_out);
#else
strcpy(lib->name, libname);
#endif
fp = fopen(lib->name, "rb");
lib->name = t_out;
fp = fopen(lib->name.u8string().c_str(), "rb");
if (fp == nullptr) {
return 0; // CF_NO_FILE;
}
@ -216,50 +201,30 @@ void cf_Close() {
Libraries = next;
}
}
// Specify a directory to look in for files
// Parameters: path - the directory path. Can be relative to the current cur (the full path will be stored)
// ext - if NULL, look in this dir for all files. If non-null, it is a
// NULL-terminated
// list of file extensions, & the dir will only be searched
// for files with a matching extension Returns: true if directory added, else false
int cf_SetSearchPath(const char *path, ...) {
if (strlen(path) >= _MAX_PATH)
return 0;
if (N_paths >= MAX_PATHS)
return 0;
bool cf_SetSearchPath(const std::filesystem::path &path, const std::vector<std::filesystem::path> &ext_list) {
// Don't add non-existing path into search paths
if (!std::filesystem::is_directory(path))
return false;
// Get & store full path
ddio_GetFullPath(paths[N_paths].path, path);
// Set extenstions for this path
va_list exts;
va_start(exts, path);
const char *ext = va_arg(exts, const char *);
if (ext == nullptr)
paths[N_paths].specific = 0;
else {
paths[N_paths].specific = 1;
while (ext != nullptr) {
if (N_extensions >= MAX_EXTENSIONS) {
va_end(exts);
return 0;
paths.insert_or_assign(std::filesystem::absolute(path), !ext_list.empty());
// Set extensions for this path
if (!ext_list.empty()) {
for (auto const &ext : ext_list) {
if (!ext.empty()) {
extensions.insert_or_assign(ext, path);
}
strncpy(extensions[N_extensions].ext, ext, _MAX_EXT);
extensions[N_extensions].pathnum = N_paths;
N_extensions++;
ext = va_arg(exts, const char *);
}
}
// This path successfully set
N_paths++;
va_end(exts);
return 1;
return true;
}
/**
* Removes all search paths that have been added by cf_SetSearchPath
*/
void cf_ClearAllSearchPaths() {
N_paths = 0;
N_extensions = 0;
paths.clear();
extensions.clear();
}
/**
@ -268,11 +233,10 @@ void cf_ClearAllSearchPaths() {
* @param libhandle
* @return
*/
CFILE *cf_OpenFileInLibrary(const char *filename, int libhandle) {
CFILE *cf_OpenFileInLibrary(const std::filesystem::path &filename, int libhandle) {
if (libhandle <= 0)
return nullptr;
CFILE *cfile;
std::shared_ptr<library> lib = Libraries;
// find the library that we want to use
@ -288,13 +252,14 @@ CFILE *cf_OpenFileInLibrary(const char *filename, int libhandle) {
}
// now do a binary search for the file entry
int i, first = 0, last = lib->nfiles - 1, c, found = 0;
int i, first = 0, last = lib->nfiles - 1, c;
bool found = false;
do {
i = (first + last) / 2;
c = stricmp(filename, lib->entries[i]->name); // compare to current
if (c == 0) { // found it
found = 1;
c = stricmp(filename.u8string().c_str(), lib->entries[i]->name); // compare to current
if (c == 0) {
found = true;
break;
}
if (first >= last) // exhausted search
@ -316,14 +281,15 @@ CFILE *cf_OpenFileInLibrary(const char *filename, int libhandle) {
fp = lib->file;
lib->file = nullptr;
} else {
fp = fopen(lib->name, "rb");
fp = fopen(lib->name.u8string().c_str(), "rb");
if (!fp) {
mprintf(1, "Error opening library <%s> when opening file <%s>; errno=%d.", lib->name, filename, errno);
mprintf(1, "Error opening library <%s> when opening file <%s>; errno=%d.",
lib->name.u8string().c_str(), filename.u8string().c_str(), errno);
Int3();
return nullptr;
}
}
cfile = (CFILE *)mem_malloc(sizeof(*cfile));
CFILE *cfile = (CFILE *)mem_malloc(sizeof(*cfile));
if (!cfile)
Error("Out of memory in cf_OpenFileInLibrary()");
cfile->name = lib->entries[i]->name;
@ -368,9 +334,10 @@ CFILE *open_file_in_lib(const char *filename) {
fp = lib->file;
lib->file = nullptr;
} else {
fp = fopen(lib->name, "rb");
fp = fopen(lib->name.u8string().c_str(), "rb");
if (!fp) {
mprintf(1, "Error opening library <%s> when opening file <%s>; errno=%d.", lib->name, filename, errno);
mprintf(1, "Error opening library <%s> when opening file <%s>; errno=%d.", lib->name.u8string().c_str(),
filename, errno);
Int3();
return nullptr;
}
@ -394,363 +361,165 @@ CFILE *open_file_in_lib(const char *filename) {
return nullptr;
}
#ifdef __LINUX__
#include <glob.h>
static int globerrfn(const char *path, int err) {
mprintf(0, "Error accessing %s: %s .... \n", path, strerror(err));
return 0;
}
class CFindFiles {
public:
CFindFiles() { globindex = -1; }
bool Start(const char *wildcard, char *namebuf);
bool Next(char *namebuf);
void Close();
private:
int globindex;
glob_t ffres;
};
bool CFindFiles::Start(const char *wildcard, char *namebuf) {
ASSERT(wildcard);
ASSERT(namebuf);
if (globindex != -1)
Close();
int rc, flags;
flags = GLOB_MARK;
rc = glob(wildcard, flags, globerrfn, &ffres);
if (rc == GLOB_NOSPACE) {
mprintf(0, "Out of space during glob\n");
globindex = -1;
return false;
}
if (!ffres.gl_pathc) {
globindex = -1;
return false;
std::filesystem::path cf_FindRealFileNameCaseInsensitive(const std::filesystem::path &fname,
const std::filesystem::path &directory) {
// Dumb check, maybe there already all ok?
if (exists((directory / fname))) {
return fname.filename();
}
globindex = 0;
char ext[256];
ddio_SplitPath(ffres.gl_pathv[0], nullptr, namebuf, ext);
strcat(namebuf, ext);
return true;
}
std::filesystem::path result, search_path, search_file;
bool CFindFiles::Next(char *namebuf) {
ASSERT(namebuf);
if (globindex == -1)
return false;
globindex++;
if (globindex >= ffres.gl_pathc)
return false;
search_path = directory / fname.parent_path();
search_file = fname.filename();
char ext[256];
ddio_SplitPath(ffres.gl_pathv[globindex], nullptr, namebuf, ext);
strcat(namebuf, ext);
return true;
}
// If directory does not exist, nothing to search.
if (!std::filesystem::is_directory(search_path) || search_file.empty()) {
return {};
}
void CFindFiles::Close() {
if (globindex == -1)
return;
globindex = -1;
globfree(&ffres);
}
static FILE *open_file_in_directory_case_sensitive(const char *directory, const char *filename, const char *mode,
char *new_filename);
// Search component in search_path
auto const &it = std::filesystem::directory_iterator(search_path);
bool cf_FindRealFileNameCaseInsenstive(const char *directory, const char *fname, char *new_filename) {
bool use_dir = false;
char dir_to_use[_MAX_PATH];
char file_to_use[_MAX_PATH];
auto found = std::find_if(it, end(it), [&search_file, &search_path, &result](const auto& dir_entry) {
return stricmp(dir_entry.path().filename().u8string().c_str(), search_file.u8string().c_str()) == 0;
});
char *real_dir, *real_file;
if (directory) {
// there is a directory for this path
use_dir = true;
real_dir = (char *)directory;
real_file = (char *)fname;
if (found != end(it)) {
// Match, append to result
result = found->path();
search_path = result;
} else {
// there may be a directory in the path (*sigh*)
char t_ext[256];
char t_dir[_MAX_PATH];
char t_filename[_MAX_PATH];
ddio_SplitPath(fname, t_dir, t_filename, t_ext);
if (strlen(t_dir) > 0) {
use_dir = true;
strcpy(dir_to_use, t_dir);
real_dir = (char *)dir_to_use;
strcpy(file_to_use, t_filename);
strcat(file_to_use, t_ext);
real_file = (char *)file_to_use;
mprintf(1, "CFILE: Found directory \"%s\" in filename, new filename is \"%s\"\n", real_dir, real_file);
} else {
use_dir = false;
real_dir = nullptr;
real_file = (char *)fname;
}
// Component not found, mission failed
return {};
}
// build up a list of filenames in the current directory that begin with the lowercase and
// upper case first letter of the filename
// do the case of the first letter to start
int case_val;
char wildcard_pattern[_MAX_PATH];
int iterations = 1;
bool found_match = false;
if ((real_file[0] >= 'a' && real_file[0] <= 'z') || (real_file[0] >= 'A' && real_file[0] <= 'Z')) {
// alpha first letter...we need to do 2 iterations
iterations = 2;
}
for (case_val = 0; case_val < iterations; case_val++) {
if (case_val) {
// do the opposite case of the first letter
char first_letter;
first_letter = real_file[0];
if (first_letter >= 'a' && first_letter <= 'z') {
// we need to uppercase the letter
first_letter = toupper(first_letter);
} else {
// we need to lowercase the letter
first_letter = tolower(first_letter);
}
// create a wildcard patter full of ? replacing letters (except the first one)
char *wptr = wildcard_pattern;
char *fptr = &real_file[1];
*wptr = first_letter;
wptr++;
while (*fptr) {
if (isalpha(*fptr)) {
*wptr = '?';
} else {
*wptr = *fptr;
}
fptr++;
wptr++;
}
*wptr = '\0';
} else {
// use the case of the first letter
// create a wildcard patter full of ? replacing letters (except the first one)
char *wptr = wildcard_pattern;
char *fptr = &real_file[1];
*wptr = real_file[0];
wptr++;
while (*fptr) {
if (isalpha(*fptr)) {
*wptr = '?';
} else {
*wptr = *fptr;
}
fptr++;
wptr++;
}
*wptr = '\0';
}
// now tack on a directory if we are to use a directory
char *wpattern;
char fullpath[_MAX_PATH];
if (use_dir) {
ddio_MakePath(fullpath, real_dir, wildcard_pattern, NULL);
wpattern = fullpath;
} else {
wpattern = wildcard_pattern;
}
// ok, we have our wildcard pattern, get all the files that match it
// and search them looking for a match (case insensitive)
char namebuffer[_MAX_PATH];
bool gotfile;
CFindFiles ff;
for (gotfile = ff.Start(wpattern, namebuffer); gotfile; gotfile = ff.Next(namebuffer)) {
if (!stricmp(namebuffer, real_file)) {
// we found a match!
found_match = true;
break;
}
}
ff.Close();
if (found_match) {
strcpy(new_filename, namebuffer);
mprintf(1, "CFILE: Using \"%s\" instead of \"%s\"\n", new_filename, real_file);
break;
}
}
return found_match;
return result.filename();
}
FILE *open_file_in_directory_case_sensitive(const char *directory, const char *filename, const char *mode,
char *new_filename) {
char t_dir[_MAX_PATH];
ddio_SplitPath(filename, t_dir, nullptr, nullptr);
if (cf_FindRealFileNameCaseInsenstive(directory, filename, new_filename)) {
// we have a file, open it open and use it
char full_path[_MAX_PATH * 2];
// if we had a directory as part of the file name, put it back in
if (strlen(t_dir) > 0)
directory = t_dir;
if (directory != nullptr) {
ddio_MakePath(full_path, directory, new_filename, NULL);
} else {
strcpy(full_path, new_filename);
}
return fopen(full_path, mode);
}
return nullptr;
}
#endif
// look for the file in the specified directory
static CFILE *open_file_in_directory(const std::filesystem::path &filename, const char *mode,
const std::filesystem::path &directory);
// look for the file in the specified directory
static CFILE *open_file_in_directory(const char *filename, const char *mode, const char *directory);
// look for the file in the specified directory
CFILE *open_file_in_directory(const char *filename, const char *mode, const char *directory) {
CFILE *open_file_in_directory(const std::filesystem::path &filename, const char *mode,
const std::filesystem::path &directory) {
FILE *fp;
CFILE *cfile;
char path[_MAX_PATH * 2];
std::filesystem::path using_filename;
char tmode[3] = "rb";
if (directory != nullptr) {
if (std::filesystem::is_directory(directory)) {
// Make a full path
ddio_MakePath(path, directory, filename, NULL);
} else // no directory specified, so just use filename passed
strcpy(path, filename);
using_filename = directory / filename;
} else {
// no directory specified, so just use filename passed
using_filename = filename;
}
// set read or write mode
tmode[0] = mode[0];
// if mode is "w", then open in text or binary as requested. If "r", alsway open in "rb"
// if mode is "w", then open in text or binary as requested. If "r", always open in "rb"
tmode[1] = (mode[0] == 'w') ? mode[1] : 'b';
// try to open file
fp = fopen(path, tmode);
fp = fopen(using_filename.u8string().c_str(), tmode);
if (!fp) {
#ifdef __LINUX__
// for Filesystems with case sensitive files we'll check for different versions of the filename
// with different case's.
if (fp) {
// found the file, open it
cfile = (CFILE *)mem_malloc(sizeof(*cfile));
if (!cfile)
Error("Out of memory in open_file_in_directory()");
cfile->name = (char *)mem_malloc(sizeof(char) * (strlen(filename) + 1));
if (!cfile->name)
Error("Out of memory in open_file_in_directory()");
strcpy(cfile->name, filename);
cfile->file = fp;
cfile->lib_handle = -1;
cfile->size = ddio_GetFileLength(fp);
cfile->lib_offset = 0; // 0 means on disk, not in HOG
cfile->position = 0;
cfile->flags = 0;
return cfile;
} else {
// try different cases of the filename
char using_filename[_MAX_PATH];
fp = open_file_in_directory_case_sensitive(directory, filename, tmode, using_filename);
if (!fp) {
// no dice
return nullptr;
// If we tried to open file for reading, assume there maybe case-sensitive files
if (tmode[0] == 'r') {
// Try different cases of the filename
using_filename = cf_FindRealFileNameCaseInsensitive(filename, directory);
if (using_filename.empty()) {
// just give up
return nullptr;
}
if (std::filesystem::is_directory(directory)) {
// Make a full path
using_filename = directory / using_filename;
}
fp = fopen(using_filename.u8string().c_str(), tmode);
if (!fp) {
// no dice
return nullptr;
}
} else {
// found a version of the file!
mprintf(0, "CFILE: Unable to find %s, but using %s instead\n", filename, using_filename);
cfile = (CFILE *)mem_malloc(sizeof(*cfile));
if (!cfile)
Error("Out of memory in open_file_in_directory()");
cfile->name = (char *)mem_malloc(sizeof(char) * (strlen(using_filename) + 1));
if (!cfile->name)
Error("Out of memory in open_file_in_directory()");
strcpy(cfile->name, using_filename);
cfile->file = fp;
cfile->lib_handle = -1;
cfile->size = ddio_GetFileLength(fp);
cfile->lib_offset = 0; // 0 means on disk, not in HOG
cfile->position = 0;
cfile->flags = 0;
return cfile;
// Error on writing file
return nullptr;
}
}
#else
if (!fp) // didn't get file
return NULL;
else { // got file
cfile = (CFILE *)mem_malloc(sizeof(*cfile));
if (!cfile)
Error("Out of memory in open_file_in_directory()");
cfile->name = (char *)mem_malloc(sizeof(char) * (strlen(filename) + 1));
if (!cfile->name)
Error("Out of memory in open_file_in_directory()");
strcpy(cfile->name, filename);
cfile->file = fp;
cfile->lib_handle = -1;
cfile->size = ddio_GetFileLength(fp);
cfile->lib_offset = 0; // 0 means on disk, not in HOG
cfile->position = 0;
cfile->flags = 0;
return cfile;
}
// We on incase-sensitive filesystem, no file means no file.
return nullptr;
#endif
} else {
using_filename = filename;
}
// found the file, open it
cfile = (CFILE *)mem_malloc(sizeof(*cfile));
if (!cfile)
Error("Out of memory in open_file_in_directory()");
cfile->name = (char *)mem_malloc(sizeof(char) * (strlen(using_filename.u8string().c_str()) + 1));
if (!cfile->name)
Error("Out of memory in open_file_in_directory()");
strcpy(cfile->name, using_filename.u8string().c_str());
cfile->file = fp;
cfile->lib_handle = -1;
cfile->size = ddio_GetFileLength(fp);
cfile->lib_offset = 0; // 0 means on disk, not in HOG
cfile->position = 0;
cfile->flags = 0;
return cfile;
}
// Opens a file for reading or writing
// If a path is specified, will try to open the file only in that path.
// If no path is specified, will look through search directories and library files.
// Parameters: filename - the name if the file, with or without a path
// mode - the standard C mode string
// Returns: the CFile handle, or NULL if file not opened
CFILE *cfopen(const char *filename, const char *mode) {
CFILE *cfopen(const std::filesystem::path &filename, const char *mode) {
CFILE *cfile;
char path[_MAX_PATH * 2], fname[_MAX_PATH * 2], ext[_MAX_EXT];
int i;
// Check for valid mode
ASSERT((mode[0] == 'r') || (mode[0] == 'w'));
ASSERT((mode[1] == 'b') || (mode[1] == 't'));
// get the parts of the pathname
ddio_SplitPath(filename, path, fname, ext);
std::filesystem::path path = filename.parent_path();
std::filesystem::path fname = filename.stem();
std::filesystem::path ext = filename.extension();
// if there is a path specified, use it instead of the libraries, search dirs, etc.
// if the file is writable, just open it, instead of looking in libs, etc.
if (strlen(path) || (mode[0] == 'w')) { // found a path
cfile = open_file_in_directory(filename, mode, nullptr); // use path specified with file
goto got_file; // don't look in libs, etc.
if (!path.empty() || (mode[0] == 'w')) {
// use path specified with file
cfile = open_file_in_directory(filename, mode, std::filesystem::path());
goto got_file; // don't look in libs, etc.
}
//@@ Don't look in current dir. mt, 3-12-97
//@@ //first look in current directory
//@@ cfile = open_file_in_directory(filename,mode,"."); //current dir
//@@ if (cfile || (mode[0] == 'w'))
//@@ goto got_file;
// First look in the directories for this file's extension
for (i = 0; i < N_extensions; i++) {
if (!strnicmp(extensions[i].ext, ext + 1, _MAX_EXT)) { // found ext
cfile = open_file_in_directory(filename, mode, paths[extensions[i].pathnum].path);
if (cfile) // || (errno != ENOENT)) //Tempoary fix so Kevin can run the game!
for (auto const &entry : extensions) {
if (!strnicmp(entry.first.u8string().c_str(), ext.u8string().c_str(), _MAX_EXT)) {
// found ext
cfile = open_file_in_directory(filename, mode, entry.second);
if (cfile) {
goto got_file;
}
}
}
// Next look in the general directories
for (i = 0; i < N_paths; i++) {
if (!paths[i].specific) {
cfile = open_file_in_directory(filename, mode, paths[i].path);
if (cfile) // || (errno != ENOENT)) //Tempoary fix so Kevin can run the game!
for (auto const &entry : paths) {
if (!entry.second) {
cfile = open_file_in_directory(filename, mode, entry.first);
if (cfile)
goto got_file;
}
}
// Lastly, try the hog files
cfile = open_file_in_lib(filename);
cfile = open_file_in_lib(filename.u8string().c_str());
got_file:;
if (cfile) {
if (mode[0] == 'w')
@ -862,7 +631,7 @@ int cfeof(CFILE *cfp) { return (cfp->position >= cfp->size); }
// Tells if the file exists
// Returns non-zero if file exists. Also tells if the file is on disk
// or in a hog - See return values in cfile.h
int cfexist(const char *filename) {
int cfexist(const std::filesystem::path &filename) {
CFILE *cfp;
int ret;
@ -870,9 +639,7 @@ int cfexist(const char *filename) {
if (!cfp) { // Didn't get file. Why?
if (errno == EACCES) // File exists, but couldn't open it
return CFES_ON_DISK; // so say it exists on the disk
// DAJ if (errno != ENOENT) //Check if error is "file not
// found"
// DAJ Int3(); //..warn if not
return CFES_NOT_FOUND; // Say we didn't find the file
}
ret = cfp->lib_offset ? CFES_IN_LIBRARY : CFES_ON_DISK;
@ -1062,9 +829,9 @@ void cf_WriteDouble(CFILE *cfp, double d) {
// Copies a file. Returns TRUE if copied ok. Returns FALSE if error opening either file.
// Throws an exception of type (cfile_error *) if the OS returns an error on read or write
bool cf_CopyFile(char *dest, const char *src, int copytime) {
bool cf_CopyFile(const std::filesystem::path &dest, const std::filesystem::path &src, int copytime) {
CFILE *infile, *outfile;
if (!stricmp(dest, src))
if (!stricmp(dest.u8string().c_str(), src.u8string().c_str()))
return true; // don't copy files if they are the same
infile = (CFILE *)cfopen(src, "rb");
if (!infile)
@ -1092,10 +859,9 @@ bool cf_CopyFile(char *dest, const char *src, int copytime) {
// c=cf_ReadByte (infile);
// cf_WriteByte (outfile,c);
}
int infile_lib_offset = infile->lib_offset;
cfclose(infile);
cfclose(outfile);
if (!infile_lib_offset && copytime) {
if (!infile->lib_offset && copytime) {
cf_CopyFileTime(dest, src);
}
return true;
@ -1103,10 +869,12 @@ bool cf_CopyFile(char *dest, const char *src, int copytime) {
// Checks to see if two files are different.
// Returns TRUE if the files are different, or FALSE if they are the same.
bool cf_Diff(const char *a, const char *b) { return (ddio_FileDiff(a, b)); }
bool cf_Diff(const std::filesystem::path &a, const std::filesystem::path &b) { return (ddio_FileDiff(a, b)); }
// Copies the file time from one file to another
void cf_CopyFileTime(char *dest, const char *src) { ddio_CopyFileTime(dest, src); }
void cf_CopyFileTime(const std::filesystem::path &dest, const std::filesystem::path &src) {
ddio_CopyFileTime(dest, src);
}
// Changes a files attributes (ie read/write only)
void cf_ChangeFileAttributes(const char *name, int attr) {
@ -1176,10 +944,8 @@ uint32_t cf_CalculateFileCRC(CFILE *infile) {
return crc ^ 0xffffffffl;
}
uint32_t cf_GetfileCRC(char *src) {
CFILE *infile;
infile = (CFILE *)cfopen(src, "rb");
uint32_t cf_GetfileCRC(const std::filesystem::path &src) {
CFILE *infile = cfopen(src, "rb");
if (!infile)
return 0xFFFFFFFF;
@ -1264,11 +1030,11 @@ void cf_LibraryFindClose() {
cfile_search_ispattern = false;
}
bool cf_IsFileInHog(const char *filename, const char *hogname) {
bool cf_IsFileInHog(const std::filesystem::path &filename, const std::filesystem::path &hogname) {
std::shared_ptr<library> lib = Libraries;
while (lib) {
if (stricmp(lib->name, hogname) == 0) {
if (stricmp(lib->name.u8string().c_str(), hogname.u8string().c_str()) == 0) {
// Now look for filename
CFILE *cf;
cf = cf_OpenFileInLibrary(filename, lib->handle);

View File

@ -97,6 +97,8 @@
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <filesystem>
#include <vector>
#include "pstypes.h"
@ -140,34 +142,41 @@ enum CFileExitStatus {
};
// See if a file is in a hog
bool cf_IsFileInHog(const char *filename, const char *hogname);
bool cf_IsFileInHog(const std::filesystem::path& filename, const std::filesystem::path& hogname);
// Opens a HOG file. Future calls to cfopen(), etc. will look in this HOG.
// Parameters: libname - the path & filename of the HOG file
// NOTE: libname must be valid for the entire execution of the program. Therefore, it should either
// be a fully-specified path name, or the current directory must not change.
// Returns: 0 if error, else library handle that can be used to close the library
int cf_OpenLibrary(const char *libname);
int cf_OpenLibrary(const std::filesystem::path& libname);
// Closes a library file.
// Parameters: handle: the handle returned by cf_OpenLibrary()
void cf_CloseLibrary(int handle);
#ifdef __LINUX__
// Maps fixed case file name to actual case on disk
// Parameters: directory: optional directory to search within (can be NULL)
// filename: the fixed case name to map to reality
// new_filename: buffer to store mapped name, must be at least _MAX_PATH bytes
// Returns: false if error, true if translated
bool cf_FindRealFileNameCaseInsenstive(const char *directory, const char *filename, char *new_filename);
#endif
/**
* Returns fixed case file name to actual case on disk for case-sensitive filesystems (Linux).
* @param fname the fixed case name to map to reality
* @param directory optional directory to search within (default - current path)
* @return filename with actual case name or empty path if there no mapping in filesystem
* @note This function returns only filename without directory part, i.e.
* cf_FindRealFileNameCaseInsensitive("test/test.txt") will return only "test.txt" on success.
*/
std::filesystem::path cf_FindRealFileNameCaseInsensitive(const std::filesystem::path &fname,
const std::filesystem::path &directory = ".");
// Specify a directory to look in for files
// Variable arguments is a NULL-terminated list of extensions
// If no extensions are specified, look in this directory for all files.
// Otherwise, the directory will only be searched for files that match
// one of the listed extensions.
int cf_SetSearchPath(const char *path, ...);
/**
* Add directory path into paths to look in for files. If ext_list is empty,
* look in this directory for all files. Otherwise, the directory will only
* be searched for files that match one of the listed extensions.
* @param path directory to add; should be existing and resolvable directory.
* @param ext_list list of extensions, which only searched on that directory.
* @return
* false: path is not a real directory;
* true: path was successfully added.
*/
bool cf_SetSearchPath(const std::filesystem::path& path, const std::vector<std::filesystem::path>& ext_list = {});
// Removes all search paths that have been added by cf_SetSearchPath
void cf_ClearAllSearchPaths();
@ -178,13 +187,13 @@ void cf_ClearAllSearchPaths();
// Parameters: filename - the name if the file, with or without a path
// mode - the standard C mode string
// Returns: the CFile handle, or NULL if file not opened
CFILE *cfopen(const char *filename, const char *mode);
CFILE *cfopen(const std::filesystem::path& filename, const char *mode);
// Opens a file for reading in a library, given the library id.
// Works just like cfopen, except it assumes "rb" mode and forces the file to be
// opened from the given library. Returns the CFILE handle or NULL if file
// couldn't be found or open.
CFILE *cf_OpenFileInLibrary(const char *filename, int libhandle);
CFILE *cf_OpenFileInLibrary(const std::filesystem::path& filename, int libhandle);
// Returns the length of the specified file
// Parameters: cfp - the file pointer returned by cfopen()
@ -210,7 +219,7 @@ int cfeof(CFILE *cfp);
// Tells if the file exists
// Returns non-zero if file exists. Also tells if the file is on disk
// or in a hog - See return values in cfile.h
int cfexist(const char *filename);
int cfexist(const std::filesystem::path& filename);
// Reads the specified number of bytes from a file into the buffer
// DO NOT USE THIS TO READ STRUCTURES. This function is for byte
@ -302,14 +311,14 @@ void cf_WriteDouble(CFILE *cfp, double d);
// Copies a file. Returns TRUE if copied ok. Returns FALSE if error opening either file.
// Throws an exception of type (cfile_error *) if the OS returns an error on read or write
// If copytime is nonzero, copies the filetime info as well
bool cf_CopyFile(char *dest, const char *src, int copytime = 0);
bool cf_CopyFile(const std::filesystem::path &dest, const std::filesystem::path &src, int copytime = 0);
// Checks to see if two files are different.
// Returns TRUE if the files are different, or FALSE if they are the same.
bool cf_Diff(const char *a, const char *b);
bool cf_Diff(const std::filesystem::path &a, const std::filesystem::path &b);
// Copies the file time from one file to another
void cf_CopyFileTime(char *dest, const char *src);
void cf_CopyFileTime(const std::filesystem::path &dest, const std::filesystem::path &src);
// Changes a files attributes (ie read/write only)
void cf_ChangeFileAttributes(const char *name, int attr);
@ -318,7 +327,7 @@ void cf_ChangeFileAttributes(const char *name, int attr);
void cf_Rewind(CFILE *fp);
// Calculates a 32 bit CRC
uint32_t cf_GetfileCRC(char *src);
uint32_t cf_GetfileCRC(const std::filesystem::path& src);
uint32_t cf_CalculateFileCRC(CFILE *fp); // same as cf_GetfileCRC, except works with CFILE pointers
// the following cf_LibraryFind function are similar to the ddio_Find functions as they look

View File

@ -0,0 +1,12 @@
add_executable(cfile_tests
cfile_tests.cpp
)
target_link_libraries(cfile_tests PRIVATE
GTest::gtest_main
cfile
)
target_include_directories(cfile_tests PRIVATE ${PROJECT_SOURCE_DIR}/lib)
gtest_discover_tests(cfile_tests
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/cfile/tests
)

View File

View File

View File

Binary file not shown.

124
cfile/tests/cfile_tests.cpp Normal file
View File

@ -0,0 +1,124 @@
/*
* Descent 3
* Copyright (C) 2024 Descent Developers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <algorithm>
#include <filesystem>
#include <vector>
#include <gtest/gtest.h>
#include "cfile.h"
TEST(D3, CFileIO) {
int lib_handle = cf_OpenLibrary("TestDir/test.hog");
CFILE *file_handle = cfopen("lowercase.txt", "rb");
char buf[5];
cf_ReadString(buf, 5, file_handle);
EXPECT_STREQ(buf, "TEST");
cf_Rewind(file_handle);
EXPECT_EQ(cf_ReadByte(file_handle), 84);
cf_Rewind(file_handle);
EXPECT_EQ(cf_ReadShort(file_handle), 17748);
cf_Rewind(file_handle);
EXPECT_EQ(cf_ReadInt(file_handle), 1414743380);
cf_Rewind(file_handle);
cf_CloseLibrary(lib_handle);
}
TEST(D3, CFileLibrary) {
// First pass - without search path in "TestDir" (i.e. not search actual files in directory)
// Second pass - with search path (files in directory goes first)
for (int i = 0; i < 2; i++) {
if (i != 0) {
EXPECT_EQ(cf_SetSearchPath("TestDir"), true);
}
int lib_handle = cf_OpenLibrary("TestDir/test.hog");
EXPECT_NE(lib_handle, 0);
CFILE *file_handle = cf_OpenFileInLibrary("lowercase.txt", lib_handle);
EXPECT_NE(file_handle, nullptr);
file_handle = cfopen("lowercase.txt", "rb");
EXPECT_NE(file_handle, nullptr);
// Length in hog is 4, in directory is 0
EXPECT_EQ(cfilelength(file_handle), i == 0 ? 4 : 0);
EXPECT_EQ(cf_CalculateFileCRC(file_handle), i == 0 ? 4008350648 : 0);
cf_ClearAllSearchPaths();
cf_CloseLibrary(lib_handle);
}
// Try to search on non-initialized paths and files
CFILE *file_handle = cfopen("lowercase.txt", "rb");
EXPECT_EQ(file_handle, nullptr);
}
TEST(D3, CFileCaseSensitiveSearchNew) {
const std::vector<std::filesystem::path> test_paths = {
std::filesystem::path("TestDir") / "CamelCase.txt",
std::filesystem::path("TestDir") / "lowercase.txt",
std::filesystem::path("TestDir") / "UPPERCASE.TXT",
};
std::filesystem::path filename_new = cf_FindRealFileNameCaseInsensitive("no-exist-file.txt", "no-exist-dir");
EXPECT_TRUE(filename_new.empty());
filename_new = cf_FindRealFileNameCaseInsensitive("no-exist-file.txt");
EXPECT_TRUE(filename_new.empty());
auto cwd = std::filesystem::current_path();
for (auto const &item : test_paths) {
auto directory = cwd / item.parent_path();
std::filesystem::path file = item.filename();
std::string file_lc = item.filename().u8string();
std::transform(file_lc.begin(), file_lc.end(), file_lc.begin(), ::tolower);
std::string file_uc = item.filename().u8string();
std::transform(file_uc.begin(), file_uc.end(), file_uc.begin(), ::toupper);
EXPECT_FALSE(cf_FindRealFileNameCaseInsensitive(file_lc, directory).empty());
EXPECT_FALSE(cf_FindRealFileNameCaseInsensitive(file_uc, directory).empty());
EXPECT_FALSE(cf_FindRealFileNameCaseInsensitive(directory / file_lc).empty());
EXPECT_FALSE(cf_FindRealFileNameCaseInsensitive(directory / file_uc).empty());
// Now try case-insensitive path with non-existing directory in search.
// Expected not found on case-sensitive fs.
file_lc = item.u8string();
std::transform(file_lc.begin(), file_lc.end(), file_lc.begin(), ::tolower);
file_uc = item.u8string();
std::transform(file_uc.begin(), file_uc.end(), file_uc.begin(), ::toupper);
if (std::filesystem::is_regular_file(file_lc)) {
EXPECT_FALSE(cf_FindRealFileNameCaseInsensitive(file_lc, cwd).empty());
EXPECT_FALSE(cf_FindRealFileNameCaseInsensitive(file_lc).empty());
} else {
EXPECT_TRUE(cf_FindRealFileNameCaseInsensitive(file_lc, cwd).empty());
EXPECT_TRUE(cf_FindRealFileNameCaseInsensitive(file_lc).empty());
}
if (std::filesystem::is_regular_file(file_uc)) {
EXPECT_FALSE(cf_FindRealFileNameCaseInsensitive(file_uc, cwd).empty());
EXPECT_FALSE(cf_FindRealFileNameCaseInsensitive(file_uc).empty());
} else {
EXPECT_TRUE(cf_FindRealFileNameCaseInsensitive(file_uc, cwd).empty());
EXPECT_TRUE(cf_FindRealFileNameCaseInsensitive(file_uc).empty());
}
}
}

View File

@ -313,38 +313,25 @@ void ddio_MouseSetVCoords(int width, int height);
// Gets the full path of the executable file
bool ddio_GetBinaryPath(char *exec_path, size_t len);
// creates or destroys a directory or folder on disk
// This pathname is *RELATIVE* not fully qualified
bool ddio_CreateDir(const char *path);
bool ddio_RemoveDir(const char *path);
// deletes a file. Returns 1 if successful, 0 on failure
// This pathname is *RELATIVE* not fully qualified
int ddio_DeleteFile(const char *name);
// Save/Restore the current working directory
void ddio_SaveWorkingDir(void);
void ddio_RestoreWorkingDir(void);
// retrieve the current working folder where file operation will occur.
// Note ---> The path in Get/Set working directory is in the *LOCAL* file system's syntax
// This pathname is relative *OR* fully qualified
void ddio_GetWorkingDir(char *path, int len);
bool ddio_SetWorkingDir(const char *path);
// Checks if a directory exists (returns 1 if it does, 0 if not)
// This pathname is *RELATIVE* not fully qualified
bool ddio_DirExists(const char *path);
// get a file length of a FILE
int ddio_GetFileLength(FILE *filePtr);
// check if two files are different
// This pathname is *RELATIVE* not fully qualified
bool ddio_FileDiff(const char *fileNameA, const char *fileNameB);
bool ddio_FileDiff(const std::filesystem::path &path1, const std::filesystem::path &path2);
// copies one files timestamp to another
void ddio_CopyFileTime(char *dest, const char *src);
void ddio_CopyFileTime(const std::filesystem::path &dest, const std::filesystem::path &src);
// Split a pathname into its component parts
// The path in splitpath is in the *LOCAL* file system's syntax

View File

@ -83,24 +83,18 @@
// ---------------------------------------------------------------------------
// File operations
// creates a directory or folder on disk
bool ddio_CreateDir(const char *path) { return (mkdir(path, S_IRWXU)) ? false : true; }
// destroys a directory
bool ddio_RemoveDir(const char *path) { return (rmdir(path)) ? false : true; }
// retrieve the current working folder where file operation will occur.
void ddio_GetWorkingDir(char *path, int len) { getcwd(path, len); }
bool ddio_SetWorkingDir(const char *path) { return (chdir(path)) ? false : true; }
bool ddio_FileDiff(const char *path1, const char *path2) {
struct stat abuf, bbuf;
bool ddio_FileDiff(const std::filesystem::path &path1, const std::filesystem::path &path2) {
struct stat abuf{}, bbuf{};
if (stat(path1, &abuf))
if (stat(path1.u8string().c_str(), &abuf))
Int3(); // error getting stat info
if (stat(path2, &bbuf))
if (stat(path2.u8string().c_str(), &bbuf))
Int3(); // error getting stat info
if ((abuf.st_size != bbuf.st_size) || (abuf.st_mtime != bbuf.st_mtime))
@ -200,43 +194,23 @@ void ddio_SplitPath(const char *srcPath, char *path, char *filename, char *ext)
}
}
void ddio_CopyFileTime(char *destname, const char *srcname) {
struct stat abuf;
void ddio_CopyFileTime(const std::filesystem::path &dest, const std::filesystem::path &src) {
struct stat abuf{};
if (stat(srcname, &abuf))
if (stat(src.u8string().c_str(), &abuf))
Int3();
struct utimbuf bbuf;
struct utimbuf bbuf{};
bbuf.actime = abuf.st_atime;
bbuf.modtime = abuf.st_mtime;
if (utime(destname, &bbuf))
if (utime(dest.u8string().c_str(), &bbuf))
Int3();
}
// deletes a file. Returns 1 if successful, 0 on failure
int ddio_DeleteFile(const char *name) { return (!unlink(name)); }
// Save/Restore the current working directory
static char SavedWorkingDir[_MAX_DIR];
void ddio_SaveWorkingDir(void) { ddio_GetWorkingDir(SavedWorkingDir, _MAX_DIR); }
void ddio_RestoreWorkingDir(void) { ddio_SetWorkingDir(SavedWorkingDir); }
// Checks if a directory exists (returns 1 if it does, 0 if not)
// This pathname is *RELATIVE* not fully qualified
bool ddio_DirExists(const char *path) {
bool res;
ddio_SaveWorkingDir();
res = ddio_SetWorkingDir(path);
ddio_RestoreWorkingDir();
return (res) ? true : false;
}
// rcg06192000 extern "C" is my add, so nettest would link.
// extern "C"
//{

View File

@ -156,24 +156,18 @@
// ---------------------------------------------------------------------------
// File operations
// creates a directory or folder on disk
bool ddio_CreateDir(const char *path) { return (CreateDirectory(path, NULL)) ? true : false; }
// destroys a directory
bool ddio_RemoveDir(const char *path) { return (RemoveDirectory(path)) ? true : false; }
// retrieve the current working folder where file operation will occur.
void ddio_GetWorkingDir(char *path, int len) { GetCurrentDirectory(len, path); }
bool ddio_SetWorkingDir(const char *path) { return (SetCurrentDirectory(path)) ? true : false; }
bool ddio_FileDiff(const char *path1, const char *path2) {
bool ddio_FileDiff(const std::filesystem::path &path1, const std::filesystem::path &path2) {
struct _stat abuf, bbuf;
if (_stat(path1, &abuf))
if (_stat(path1.u8string().c_str(), &abuf))
Int3(); // error getting stat info
if (_stat(path2, &bbuf))
if (_stat(path2.u8string().c_str(), &bbuf))
Int3(); // error getting stat info
if ((abuf.st_size != bbuf.st_size) || (abuf.st_mtime != bbuf.st_mtime))
@ -195,18 +189,18 @@ void ddio_SplitPath(const char *srcPath, char *path, char *filename, char *ext)
sprintf(path, "%s%s", drivename, dirname);
}
void ddio_CopyFileTime(char *destname, const char *srcname) {
void ddio_CopyFileTime(const std::filesystem::path &dest, const std::filesystem::path &src) {
HANDLE desthandle, srchandle;
FILETIME a, b, c;
bool first_time = 1;
try_again:;
desthandle = CreateFile(destname, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
srchandle = CreateFile(srcname, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
desthandle = CreateFile(dest.u8string().c_str(), GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
srchandle = CreateFile(src.u8string().c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (desthandle == INVALID_HANDLE_VALUE || srchandle == INVALID_HANDLE_VALUE) {
mprintf(0, "Couldn't copy file time for %s! Error=%d\n", destname, GetLastError());
mprintf(0, "Couldn't copy file time for %s! Error=%d\n", dest.u8string().c_str(), GetLastError());
if (desthandle != INVALID_HANDLE_VALUE)
CloseHandle(desthandle);
@ -236,26 +230,6 @@ try_again:;
// deletes a file. Returns 1 if successful, 0 on failure
int ddio_DeleteFile(const char *name) { return (DeleteFile(name)); }
// Save/Restore the current working directory
static char SavedWorkingDir[_MAX_DIR];
void ddio_SaveWorkingDir(void) { GetCurrentDirectory(_MAX_DIR, SavedWorkingDir); }
void ddio_RestoreWorkingDir(void) { SetCurrentDirectory(SavedWorkingDir); }
// Checks if a directory exists (returns 1 if it does, 0 if not)
// This pathname is *RELATIVE* not fully qualified
bool ddio_DirExists(const char *path) {
BOOL res;
ddio_SaveWorkingDir();
res = SetCurrentDirectory(path);
ddio_RestoreWorkingDir();
return (res) ? true : false;
}
// Constructs a path in the local file system's syntax
// newPath: stores the constructed path
// absolutePathHeader: absolute path on which the sub directories will be appended

View File

@ -763,6 +763,7 @@
#include <cstdarg>
#include <cstdio>
#include <filesystem>
#include "stdafx.h"
#include "editor.h"
@ -2019,11 +2020,11 @@ void CMainFrame::OnImportBitmap() {
mprintf(0, "Making a copy of this bitmap/anim locally...\n");
if (!anim) {
sprintf(filename, "%s\\%s", LocalManageGraphicsDir, GameBitmaps[bm_handle].name);
sprintf(filename, "%s\\%s", LocalManageGraphicsDir.u8string().c_str(), GameBitmaps[bm_handle].name);
bm_SaveFileBitmap(filename, bm_handle);
bm_FreeBitmap(bm_handle);
} else {
sprintf(filename, "%s\\%s", LocalManageGraphicsDir, GameVClips[bm_handle].name);
sprintf(filename, "%s\\%s", LocalManageGraphicsDir.u8string().c_str(), GameVClips[bm_handle].name);
SaveVClip(filename, bm_handle);
FreeVClip(bm_handle);
}
@ -2963,7 +2964,8 @@ void CMainFrame::OnTerrainView() { SetViewMode(VM_TERRAIN); }
void CMainFrame::OnMineView() {
// Make sure there's a room to switch to
for (int roomnum = 0; roomnum <= Highest_room_index; roomnum++)
int roomnum;
for (roomnum = 0; roomnum <= Highest_room_index; roomnum++)
if (Rooms[roomnum].used && !(Rooms[roomnum].flags & RF_EXTERNAL))
break;
@ -3187,7 +3189,7 @@ void CMainFrame::OnHotspotTga() {
}
if (!anim) {
sprintf(filename, "%s\\%s", LocalManageGraphicsDir, GameBitmaps[bm_handle].name);
sprintf(filename, "%s\\%s", LocalManageGraphicsDir.u8string().c_str(), GameBitmaps[bm_handle].name);
bm_SaveFileBitmap(filename, bm_handle);
bm_FreeBitmap(bm_handle);
}

View File

@ -19,6 +19,8 @@
// MegacellDialog.cpp : implementation file
//
#include <filesystem>
#include "stdafx.h"
#include "editor.h"
#include "MegacellDialog.h"
@ -1071,19 +1073,19 @@ void CMegacellDialog::CheckinTexture(int n, int tracklock_num) {
else {
// Save this textures bitmap to the network for all
char fname[255];
std::filesystem::path fname;
if (GameTextures[n].flags & TF_ANIMATED) {
sprintf(fname, "%s\\%s", ManageGraphicsDir, GameVClips[GameTextures[n].bm_handle].name);
fname = ManageGraphicsDir / GameVClips[GameTextures[n].bm_handle].name;
SaveVClip(fname, GameTextures[n].bm_handle);
sprintf(fname, "%s\\%s", LocalManageGraphicsDir, GameVClips[GameTextures[n].bm_handle].name);
fname = LocalManageGraphicsDir / GameVClips[GameTextures[n].bm_handle].name;
SaveVClip(fname, GameTextures[n].bm_handle);
} else {
sprintf(fname, "%s\\%s", ManageGraphicsDir, GameBitmaps[GameTextures[n].bm_handle].name);
fname = ManageGraphicsDir / GameBitmaps[GameTextures[n].bm_handle].name;
bm_SaveFileBitmap(fname, GameTextures[n].bm_handle);
sprintf(fname, "%s\\%s", LocalManageGraphicsDir, GameBitmaps[GameTextures[n].bm_handle].name);
fname = LocalManageGraphicsDir / GameBitmaps[GameTextures[n].bm_handle].name;
bm_SaveFileBitmap(fname, GameTextures[n].bm_handle);
}
@ -1198,7 +1200,8 @@ void CMegacellDialog::OnImportTiny() {
strcpy(GameBitmaps[bm_handle].name, filename);
// Save this textures image locally
sprintf(filename, "%s\\%s", LocalManageGraphicsDir, GameBitmaps[GameTextures[tex_handle].bm_handle].name);
sprintf(filename, "%s\\%s", LocalManageGraphicsDir.u8string().c_str(),
GameBitmaps[GameTextures[tex_handle].bm_handle].name);
mprintf(0, "Saving bitmap %s from megacell!\n", GameBitmaps[bm_handle].name);
bm_SaveFileBitmap(filename, GameTextures[tex_handle].bm_handle);
@ -1323,7 +1326,8 @@ void CMegacellDialog::OnImportSky() {
strcpy(GameBitmaps[bm_handle].name, filename);
// Save this textures image locally
sprintf(filename, "%s\\%s", LocalManageGraphicsDir, GameBitmaps[GameTextures[tex_handle].bm_handle].name);
sprintf(filename, "%s\\%s", LocalManageGraphicsDir.u8string().c_str(),
GameBitmaps[GameTextures[tex_handle].bm_handle].name);
mprintf(0, "Saving bitmap %s from megacell!\n", GameBitmaps[bm_handle].name);
bm_SaveFileBitmap(filename, GameTextures[tex_handle].bm_handle);
@ -1444,7 +1448,8 @@ void CMegacellDialog::OnImportSkyBand() {
strcpy(GameBitmaps[bm_handle].name, filename);
// Save this textures image locally
sprintf(filename, "%s\\%s", LocalManageGraphicsDir, GameBitmaps[GameTextures[tex_handle].bm_handle].name);
sprintf(filename, "%s\\%s", LocalManageGraphicsDir.u8string().c_str(),
GameBitmaps[GameTextures[tex_handle].bm_handle].name);
mprintf(0, "Saving bitmap %s from megacell!\n", GameBitmaps[bm_handle].name);
bm_SaveFileBitmap(filename, GameTextures[tex_handle].bm_handle);

View File

@ -374,7 +374,7 @@ skip_combine:;
strcpy(rp->name, roomname);
// Save it out to disk (locally)
ddio_MakePath(name, LocalRoomsDir, roomname, NULL);
ddio_MakePath(name, LocalRoomsDir.u8string().c_str(), roomname, NULL);
SaveRoom(ROOMNUM(rp), name);
}

View File

@ -223,7 +223,7 @@ bool GenericPageList::SaveTable(char *table_filename) {
return FALSE;
// First make sure we can open the table file and the temp table file
infile = cfopen(m_TableFilename, "rb");
infile = cfopen(m_TableFilename.GetBuffer(0), "rb");
if (!infile) {
mprintf(0, "Couldn't open table file to replace generic!\n");
return FALSE;

View File

@ -112,6 +112,8 @@
* $NoKeywords: $
*/
#include <filesystem>
#include "mfc_compatibility.h"
#include "editor.h"
#include "WorldObjectsDoorDialog.h"
@ -308,10 +310,8 @@ void CWorldObjectsDoorDialog::OnAddDoor() {
// Finally, save a local copy of the model/anim and alloc a tracklock
mprintf(0, "Making a copy of this model locally...\n");
char destname[100];
sprintf(destname, "%s\\%s", LocalModelsDir, Poly_models[Doors[door_handle].model_handle].name);
if (stricmp(destname, pathname)) // only copy if they are different
cf_CopyFile(destname, pathname);
std::filesystem::path destname = LocalModelsDir / Poly_models[Doors[door_handle].model_handle].name;
cf_CopyFile(destname, pathname);
mng_AllocTrackLock(cur_name, PAGETYPE_DOOR);
@ -407,7 +407,7 @@ void CWorldObjectsDoorDialog::UpdateDialog() {
// Update sounds lists
SendDlgItemMessage(IDC_DOOR_OPEN_SOUND, CB_RESETCONTENT, 0, 0);
SendDlgItemMessage(IDC_DOOR_OPEN_SOUND, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)NULL_NAME);
for (i = 0; i < MAX_SOUNDS; i++) {
for (int i = 0; i < MAX_SOUNDS; i++) {
if (Sounds[i].used)
SendDlgItemMessage(IDC_DOOR_OPEN_SOUND, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)Sounds[i].name);
}
@ -418,7 +418,7 @@ void CWorldObjectsDoorDialog::UpdateDialog() {
SendDlgItemMessage(IDC_DOOR_CLOSE_SOUND, CB_RESETCONTENT, 0, 0);
SendDlgItemMessage(IDC_DOOR_CLOSE_SOUND, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)NULL_NAME);
for (i = 0; i < MAX_SOUNDS; i++) {
for (int i = 0; i < MAX_SOUNDS; i++) {
if (Sounds[i].used)
SendDlgItemMessage(IDC_DOOR_CLOSE_SOUND, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)Sounds[i].name);
}
@ -541,11 +541,8 @@ void CWorldObjectsDoorDialog::OnCheckinDoor() {
OutrageMessageBox(ErrorString);
else {
// Save this door anim/model to the network for all
char destname[100], srcname[100];
sprintf(srcname, "%s\\%s", LocalModelsDir, Poly_models[Doors[n].model_handle].name);
sprintf(destname, "%s\\%s", NetModelsDir, Poly_models[Doors[n].model_handle].name);
std::filesystem::path srcname = LocalModelsDir / Poly_models[Doors[n].model_handle].name;
std::filesystem::path destname = NetModelsDir / Poly_models[Doors[n].model_handle].name;
cf_CopyFile(destname, srcname);
@ -769,7 +766,6 @@ void CWorldObjectsDoorDialog::OnDoorsOut() {
void CWorldObjectsDoorDialog::OnLoadDoorModel() {
char filename[255];
char curname[255];
int img_handle;
int door_handle;
int c = 1, finding_name = 1;
@ -795,8 +791,7 @@ void CWorldObjectsDoorDialog::OnLoadDoorModel() {
Doors[door_handle].model_handle = img_handle;
// Finally, save a local copy of the model
sprintf(curname, "%s\\%s", LocalModelsDir, Poly_models[Doors[door_handle].model_handle].name);
std::filesystem::path curname = LocalModelsDir / Poly_models[Doors[door_handle].model_handle].name;
cf_CopyFile(curname, filename);
UpdateDialog();

View File

@ -19,6 +19,8 @@
// WorldObjectsGenericDialog.cpp : implementation file
//
#include <filesystem>
#include "mfc_compatibility.h"
#include "editor.h"
#include "WorldObjectsGenericDialog.h"
@ -722,10 +724,8 @@ retry_name:
// Finally, save a local copy of the model/anim and alloc a tracklock
mprintf(0, "Making a copy of this model locally...\n");
char destname[100];
sprintf(destname, "%s\\%s", LocalModelsDir, Poly_models[Object_info[object_handle].render_handle].name);
if (stricmp(destname, filename)) // only copy if they are different
cf_CopyFile(destname, filename);
std::filesystem::path destname = LocalModelsDir / Poly_models[Object_info[object_handle].render_handle].name;
cf_CopyFile(destname, filename);
mng_AllocTrackLock(cur_name, PAGETYPE_GENERIC);
@ -798,21 +798,19 @@ void CWorldObjectsGenericDialog::OnGenericCheckIn() {
else {
// Save this object anim/model to the network for all
char destname[100], srcname[100];
sprintf(srcname, "%s\\%s", LocalModelsDir, Poly_models[Object_info[m_current].render_handle].name);
sprintf(destname, "%s\\%s", NetModelsDir, Poly_models[Object_info[m_current].render_handle].name);
std::filesystem::path srcname = LocalModelsDir / Poly_models[Object_info[m_current].render_handle].name;
std::filesystem::path destname = NetModelsDir / Poly_models[Object_info[m_current].render_handle].name;
cf_CopyFile(destname, srcname);
if (Object_info[m_current].med_render_handle != -1) {
sprintf(srcname, "%s\\%s", LocalModelsDir, Poly_models[Object_info[m_current].med_render_handle].name);
sprintf(destname, "%s\\%s", NetModelsDir, Poly_models[Object_info[m_current].med_render_handle].name);
srcname = LocalModelsDir / Poly_models[Object_info[m_current].med_render_handle].name;
destname = NetModelsDir / Poly_models[Object_info[m_current].med_render_handle].name;
cf_CopyFile(destname, srcname);
}
if (Object_info[m_current].lo_render_handle != -1) {
sprintf(srcname, "%s\\%s", LocalModelsDir, Poly_models[Object_info[m_current].lo_render_handle].name);
sprintf(destname, "%s\\%s", NetModelsDir, Poly_models[Object_info[m_current].lo_render_handle].name);
srcname = LocalModelsDir / Poly_models[Object_info[m_current].lo_render_handle].name;
destname = NetModelsDir / Poly_models[Object_info[m_current].lo_render_handle].name;
cf_CopyFile(destname, srcname);
}
@ -1048,7 +1046,7 @@ void CWorldObjectsGenericDialog::OnGenericChangeModel() {
}
// Finally, save a local copy of the model
sprintf(curname, "%s\\%s", LocalModelsDir, Poly_models[img_handle].name);
sprintf(curname, "%s\\%s", LocalModelsDir.u8string().c_str(), Poly_models[img_handle].name);
cf_CopyFile(curname, filename);
UpdateDialog();

View File

@ -121,6 +121,8 @@
* $NoKeywords: $
*/
#include <filesystem>
#include "mfc_compatibility.h"
#include "editor.h"
#include "WorldObjectsPlayerDialog.h"
@ -243,10 +245,8 @@ void CWorldObjectsPlayerDialog::OnAddPship() {
// Finally, save a local copy of the model/anim and alloc a tracklock
mprintf(0, "Making a copy of this model locally...\n");
char destname[100];
sprintf(destname, "%s\\%s", LocalModelsDir, Poly_models[Ships[ship_handle].model_handle].name);
if (stricmp(destname, filename)) // only copy if they are different
cf_CopyFile(destname, filename);
std::filesystem::path destname = LocalModelsDir / Poly_models[Ships[ship_handle].model_handle].name;
cf_CopyFile(destname, filename);
mng_AllocTrackLock(cur_name, PAGETYPE_SHIP);
@ -291,38 +291,35 @@ void CWorldObjectsPlayerDialog::OnPshipCheckin() {
OutrageMessageBox(ErrorString);
else {
// Save this ship anim/model to the network for all
char destname[100], srcname[100];
sprintf(srcname, "%s\\%s", LocalModelsDir, Poly_models[Ships[n].model_handle].name);
sprintf(destname, "%s\\%s", NetModelsDir, Poly_models[Ships[n].model_handle].name);
std::filesystem::path srcname = LocalModelsDir / Poly_models[Ships[n].model_handle].name;
std::filesystem::path destname = NetModelsDir / Poly_models[Ships[n].model_handle].name;
cf_CopyFile(destname, srcname);
if (Ships[n].dying_model_handle != -1) {
sprintf(srcname, "%s\\%s", LocalModelsDir, Poly_models[Ships[n].dying_model_handle].name);
sprintf(destname, "%s\\%s", NetModelsDir, Poly_models[Ships[n].dying_model_handle].name);
srcname = LocalModelsDir / Poly_models[Ships[n].dying_model_handle].name;
destname = NetModelsDir / Poly_models[Ships[n].dying_model_handle].name;
cf_CopyFile(destname, srcname);
}
if (Ships[n].med_render_handle != -1) {
sprintf(srcname, "%s\\%s", LocalModelsDir, Poly_models[Ships[n].med_render_handle].name);
sprintf(destname, "%s\\%s", NetModelsDir, Poly_models[Ships[n].med_render_handle].name);
srcname = LocalModelsDir / Poly_models[Ships[n].med_render_handle].name;
destname = NetModelsDir / Poly_models[Ships[n].med_render_handle].name;
cf_CopyFile(destname, srcname);
}
if (Ships[n].lo_render_handle != -1) {
sprintf(srcname, "%s\\%s", LocalModelsDir, Poly_models[Ships[n].lo_render_handle].name);
sprintf(destname, "%s\\%s", NetModelsDir, Poly_models[Ships[n].lo_render_handle].name);
srcname = LocalModelsDir / Poly_models[Ships[n].lo_render_handle].name;
destname = NetModelsDir / Poly_models[Ships[n].lo_render_handle].name;
cf_CopyFile(destname, srcname);
}
if (Ships[n].cockpit_name[0]) {
sprintf(srcname, "%s\\%s", LocalMiscDir, Ships[n].cockpit_name);
sprintf(destname, "%s\\%s", NetMiscDir, Ships[n].cockpit_name);
srcname = LocalMiscDir / Ships[n].cockpit_name;
destname = NetMiscDir / Ships[n].cockpit_name;
cf_CopyFile(destname, srcname);
}
@ -409,7 +406,6 @@ void CWorldObjectsPlayerDialog::OnPshipDelete() {
void CWorldObjectsPlayerDialog::OnPshipLoadModel() {
char filename[255];
char curname[255];
int img_handle;
int ship_handle;
int c = 1, finding_name = 1;
@ -455,7 +451,7 @@ void CWorldObjectsPlayerDialog::OnPshipLoadModel() {
}
// Finally, save a local copy of the model
sprintf(curname, "%s\\%s", LocalModelsDir, Poly_models[img_handle].name);
std::filesystem::path curname = LocalModelsDir / Poly_models[img_handle].name;
cf_CopyFile(curname, filename);
UpdateDialog();
@ -916,7 +912,6 @@ void CWorldObjectsPlayerDialog::OnPshipEditPhysics() {
void CWorldObjectsPlayerDialog::OnPshipDyingModel() {
char filename[_MAX_PATH];
char curname[_MAX_PATH];
int img_handle;
int ship_handle;
int c = 1, finding_name = 1;
@ -943,7 +938,7 @@ void CWorldObjectsPlayerDialog::OnPshipDyingModel() {
// Finally, save a local copy of the model
sprintf(curname, "%s\\%s", LocalModelsDir, Poly_models[Ships[ship_handle].dying_model_handle].name);
std::filesystem::path curname = LocalModelsDir / Poly_models[Ships[ship_handle].dying_model_handle].name;
cf_CopyFile(curname, filename);
UpdateDialog();
@ -980,7 +975,7 @@ void CWorldObjectsPlayerDialog::OnPshipCockpit() {
sprintf(Ships[D3EditState.current_ship].cockpit_name, "%s%s", curname, ext);
// Finally, save a local copy of the inf file.
sprintf(curname, "%s\\%s", LocalMiscDir, Ships[D3EditState.current_ship].cockpit_name);
sprintf(curname, "%s\\%s", LocalMiscDir.u8string().c_str(), Ships[D3EditState.current_ship].cockpit_name);
cf_CopyFile(curname, filename);
UpdateDialog();

View File

@ -117,6 +117,8 @@
// WorldSoundsDialog.cpp : implementation file
//
#include <filesystem>
#include "stdafx.h"
#include "pserror.h"
@ -248,10 +250,8 @@ void CWorldSoundsDialog::OnAddSound() {
// Finally, save a local copy of the .wav and alloc a tracklock
mprintf(0, "Making a copy of this sound locally...\n");
char destname[100];
sprintf(destname, "%s\\%s", LocalSoundsDir, SoundFiles[Sounds[sound_handle].sample_index].name);
if (stricmp(destname, filename)) // only copy if they are different
cf_CopyFile(destname, filename);
std::filesystem::path destname = LocalSoundsDir / SoundFiles[Sounds[sound_handle].sample_index].name;
cf_CopyFile(destname, filename);
mng_AllocTrackLock(cur_name, PAGETYPE_SOUND);
@ -300,10 +300,8 @@ void CWorldSoundsDialog::OnCheckinSound() {
else {
// Save this sound raw to the network for all
char destname[100], srcname[100];
sprintf(srcname, "%s\\%s", LocalSoundsDir, SoundFiles[Sounds[n].sample_index].name);
sprintf(destname, "%s\\%s", NetSoundsDir, SoundFiles[Sounds[n].sample_index].name);
std::filesystem::path srcname = LocalSoundsDir / SoundFiles[Sounds[n].sample_index].name;
std::filesystem::path destname = NetSoundsDir / SoundFiles[Sounds[n].sample_index].name;
cf_CopyFile(destname, srcname);
@ -451,7 +449,6 @@ void CWorldSoundsDialog::OnLockSound() {
void CWorldSoundsDialog::OnLoadSound() {
char filename[255];
char curname[255];
int raw_handle;
int sound_handle;
int c = 1, finding_name = 1;
@ -477,7 +474,7 @@ void CWorldSoundsDialog::OnLoadSound() {
// Finally, save a local copy of the raw
sprintf(curname, "%s\\%s", LocalSoundsDir, SoundFiles[Sounds[sound_handle].sample_index].name);
std::filesystem::path curname = LocalSoundsDir / SoundFiles[Sounds[sound_handle].sample_index].name;
cf_CopyFile(curname, filename);
UpdateDialog();

View File

@ -459,10 +459,12 @@ void CWorldTexturesDialog::OnWtexdlgAddnew() {
mprintf(0, "Making a copy of this bitmap/anim locally...\n");
if (!anim) {
sprintf(filename, "%s\\%s", LocalManageGraphicsDir, GameBitmaps[GameTextures[tex_handle].bm_handle].name);
sprintf(filename, "%s\\%s", LocalManageGraphicsDir.u8string().c_str(),
GameBitmaps[GameTextures[tex_handle].bm_handle].name);
bm_SaveFileBitmap(filename, GameTextures[tex_handle].bm_handle);
} else {
sprintf(filename, "%s\\%s", LocalManageGraphicsDir, GameVClips[GameTextures[tex_handle].bm_handle].name);
sprintf(filename, "%s\\%s", LocalManageGraphicsDir.u8string().c_str(),
GameVClips[GameTextures[tex_handle].bm_handle].name);
SaveVClip(filename, GameTextures[tex_handle].bm_handle);
}
@ -1091,19 +1093,19 @@ void CWorldTexturesDialog::OnCheckin() {
else {
// Save this textures bitmap to the network for all
char fname[255];
std::filesystem::path fname;
if (GameTextures[n].flags & TF_ANIMATED) {
sprintf(fname, "%s\\%s", ManageGraphicsDir, GameVClips[GameTextures[n].bm_handle].name);
fname = ManageGraphicsDir / GameVClips[GameTextures[n].bm_handle].name;
SaveVClip(fname, GameTextures[n].bm_handle);
sprintf(fname, "%s\\%s", LocalManageGraphicsDir, GameVClips[GameTextures[n].bm_handle].name);
fname = LocalManageGraphicsDir / GameVClips[GameTextures[n].bm_handle].name;
SaveVClip(fname, GameTextures[n].bm_handle);
} else {
sprintf(fname, "%s\\%s", ManageGraphicsDir, GameBitmaps[GameTextures[n].bm_handle].name);
fname = ManageGraphicsDir / GameBitmaps[GameTextures[n].bm_handle].name;
bm_SaveFileBitmap(fname, GameTextures[n].bm_handle);
sprintf(fname, "%s\\%s", LocalManageGraphicsDir, GameBitmaps[GameTextures[n].bm_handle].name);
fname = LocalManageGraphicsDir / GameBitmaps[GameTextures[n].bm_handle].name;
bm_SaveFileBitmap(fname, GameTextures[n].bm_handle);
}
@ -1162,13 +1164,13 @@ void CWorldTexturesDialog::SaveTexturesOnClose() {
mng_ReplacePage(GameTextures[t].name, GameTextures[t].name, t, PAGETYPE_TEXTURE, 1);
char fname[255];
std::filesystem::path fname;
if (GameTextures[t].flags & TF_ANIMATED) {
sprintf(fname, "%s\\%s", LocalManageGraphicsDir, GameVClips[GameTextures[t].bm_handle].name);
fname = LocalManageGraphicsDir / GameVClips[GameTextures[t].bm_handle].name;
SaveVClip(fname, GameTextures[t].bm_handle);
} else {
sprintf(fname, "%s\\%s", LocalManageGraphicsDir, GameBitmaps[GameTextures[t].bm_handle].name);
fname = LocalManageGraphicsDir / GameBitmaps[GameTextures[t].bm_handle].name;
bm_SaveFileBitmap(fname, GameTextures[t].bm_handle);
}
}
@ -1331,10 +1333,12 @@ void CWorldTexturesDialog::OnLoadBitmap() {
mprintf(0, "Making a copy of this bitmap locally...\n");
if (anim) {
sprintf(filename, "%s\\%s", LocalManageGraphicsDir, GameVClips[GameTextures[n].bm_handle].name);
sprintf(filename, "%s\\%s", LocalManageGraphicsDir.u8string().c_str(),
GameVClips[GameTextures[n].bm_handle].name);
SaveVClip(filename, GameTextures[n].bm_handle);
} else {
sprintf(filename, "%s\\%s", LocalManageGraphicsDir, GameBitmaps[GameTextures[n].bm_handle].name);
sprintf(filename, "%s\\%s", LocalManageGraphicsDir.u8string().c_str(),
GameBitmaps[GameTextures[n].bm_handle].name);
bm_SaveFileBitmap(filename, GameTextures[n].bm_handle);
}
@ -1688,7 +1692,8 @@ Here:
for (i = 0; i < total; i++) {
tex_handle = tex_list[i];
sprintf(filename, "%s\\%s", LocalManageGraphicsDir, GameBitmaps[GameTextures[tex_handle].bm_handle].name);
sprintf(filename, "%s\\%s", LocalManageGraphicsDir.u8string().c_str(),
GameBitmaps[GameTextures[tex_handle].bm_handle].name);
bm_SaveFileBitmap(filename, GameTextures[tex_handle].bm_handle);
}
@ -1842,10 +1847,12 @@ void CWorldTexturesDialog::OnAddNewSmall() {
mprintf(0, "Making a copy of this bitmap/anim locally...\n");
if (!anim) {
sprintf(filename, "%s\\%s", LocalManageGraphicsDir, GameBitmaps[GameTextures[tex_handle].bm_handle].name);
sprintf(filename, "%s\\%s", LocalManageGraphicsDir.u8string().c_str(),
GameBitmaps[GameTextures[tex_handle].bm_handle].name);
bm_SaveFileBitmap(filename, GameTextures[tex_handle].bm_handle);
} else {
sprintf(filename, "%s\\%s", LocalManageGraphicsDir, GameVClips[GameTextures[tex_handle].bm_handle].name);
sprintf(filename, "%s\\%s", LocalManageGraphicsDir.u8string().c_str(),
GameVClips[GameTextures[tex_handle].bm_handle].name);
SaveVClip(filename, GameTextures[tex_handle].bm_handle);
}
@ -1931,10 +1938,12 @@ void CWorldTexturesDialog::OnAddNewTiny() {
mprintf(0, "Making a copy of this bitmap/anim locally...\n");
if (!anim) {
sprintf(filename, "%s\\%s", LocalManageGraphicsDir, GameBitmaps[GameTextures[tex_handle].bm_handle].name);
sprintf(filename, "%s\\%s", LocalManageGraphicsDir.u8string().c_str(),
GameBitmaps[GameTextures[tex_handle].bm_handle].name);
bm_SaveFileBitmap(filename, GameTextures[tex_handle].bm_handle);
} else {
sprintf(filename, "%s\\%s", LocalManageGraphicsDir, GameVClips[GameTextures[tex_handle].bm_handle].name);
sprintf(filename, "%s\\%s", LocalManageGraphicsDir.u8string().c_str(),
GameVClips[GameTextures[tex_handle].bm_handle].name);
SaveVClip(filename, GameTextures[tex_handle].bm_handle);
}
@ -2543,10 +2552,12 @@ void CWorldTexturesDialog::OnAddNewHuge() {
mprintf(0, "Making a copy of this bitmap/anim locally...\n");
if (!anim) {
sprintf(filename, "%s\\%s", LocalManageGraphicsDir, GameBitmaps[GameTextures[tex_handle].bm_handle].name);
sprintf(filename, "%s\\%s", LocalManageGraphicsDir.u8string().c_str(),
GameBitmaps[GameTextures[tex_handle].bm_handle].name);
bm_SaveFileBitmap(filename, GameTextures[tex_handle].bm_handle);
} else {
sprintf(filename, "%s\\%s", LocalManageGraphicsDir, GameVClips[GameTextures[tex_handle].bm_handle].name);
sprintf(filename, "%s\\%s", LocalManageGraphicsDir.u8string().c_str(),
GameVClips[GameTextures[tex_handle].bm_handle].name);
SaveVClip(filename, GameTextures[tex_handle].bm_handle);
}

View File

@ -485,10 +485,12 @@ void CWorldWeaponsDialog::OnAddWeapon() {
mprintf(0, "Making a copy of this bitmap/anim locally...\n");
if (!anim) {
sprintf(filename, "%s\\%s", LocalManageGraphicsDir, GameBitmaps[Weapons[weapon_handle].hud_image_handle].name);
sprintf(filename, "%s\\%s", LocalManageGraphicsDir.u8string().c_str(),
GameBitmaps[Weapons[weapon_handle].hud_image_handle].name);
bm_SaveFileBitmap(filename, Weapons[weapon_handle].hud_image_handle);
} else {
sprintf(filename, "%s\\%s", LocalManageGraphicsDir, GameVClips[Weapons[weapon_handle].hud_image_handle].name);
sprintf(filename, "%s\\%s", LocalManageGraphicsDir.u8string().c_str(),
GameVClips[Weapons[weapon_handle].hud_image_handle].name);
SaveVClip(filename, Weapons[weapon_handle].hud_image_handle);
}
@ -536,17 +538,17 @@ void CWorldWeaponsDialog::OnAddWeapon() {
if (!model) {
if (!anim) {
sprintf(filename, "%s\\%s", LocalManageGraphicsDir, GameBitmaps[Weapons[weapon_handle].fire_image_handle].name);
sprintf(filename, "%s\\%s", LocalManageGraphicsDir.u8string().c_str(),
GameBitmaps[Weapons[weapon_handle].fire_image_handle].name);
bm_SaveFileBitmap(filename, Weapons[weapon_handle].fire_image_handle);
} else {
sprintf(filename, "%s\\%s", LocalManageGraphicsDir, GameVClips[Weapons[weapon_handle].fire_image_handle].name);
sprintf(filename, "%s\\%s", LocalManageGraphicsDir.u8string().c_str(),
GameVClips[Weapons[weapon_handle].fire_image_handle].name);
SaveVClip(filename, Weapons[weapon_handle].fire_image_handle);
}
} else {
char destname[100];
sprintf(destname, "%s\\%s", LocalModelsDir, Poly_models[Weapons[weapon_handle].fire_image_handle].name);
if (stricmp(destname, filename)) // only copy if they are different
cf_CopyFile(destname, filename);
std::filesystem::path destname = LocalModelsDir / Poly_models[Weapons[weapon_handle].fire_image_handle].name;
cf_CopyFile(destname, filename);
}
mng_AllocTrackLock(cur_name, PAGETYPE_WEAPON);
@ -659,29 +661,27 @@ void CWorldWeaponsDialog::OnCheckinWeapon() {
OutrageMessageBox(ErrorString);
else {
// Save this weapon anim/image to the network for all
char destname[100], srcname[100];
std::filesystem::path srcname, destname;
if (Weapons[n].flags & WF_HUD_ANIMATED) {
sprintf(srcname, "%s\\%s", LocalManageGraphicsDir, GameVClips[Weapons[n].hud_image_handle].name);
sprintf(destname, "%s\\%s", ManageGraphicsDir, GameVClips[Weapons[n].hud_image_handle].name);
srcname = LocalManageGraphicsDir / GameVClips[Weapons[n].hud_image_handle].name;
destname = ManageGraphicsDir / GameVClips[Weapons[n].hud_image_handle].name;
} else {
sprintf(srcname, "%s\\%s", LocalManageGraphicsDir, GameBitmaps[Weapons[n].hud_image_handle].name);
sprintf(destname, "%s\\%s", ManageGraphicsDir, GameBitmaps[Weapons[n].hud_image_handle].name);
srcname = LocalManageGraphicsDir / GameBitmaps[Weapons[n].hud_image_handle].name;
destname = ManageGraphicsDir / GameBitmaps[Weapons[n].hud_image_handle].name;
}
cf_CopyFile(destname, srcname);
if (Weapons[n].flags & WF_IMAGE_BITMAP) {
sprintf(srcname, "%s\\%s", LocalManageGraphicsDir, GameBitmaps[Weapons[n].fire_image_handle].name);
sprintf(destname, "%s\\%s", ManageGraphicsDir, GameBitmaps[Weapons[n].fire_image_handle].name);
srcname = LocalManageGraphicsDir / GameBitmaps[Weapons[n].fire_image_handle].name;
destname = ManageGraphicsDir, GameBitmaps[Weapons[n].fire_image_handle].name;
} else if (Weapons[n].flags & WF_IMAGE_VCLIP) {
sprintf(srcname, "%s\\%s", LocalManageGraphicsDir, GameVClips[Weapons[n].fire_image_handle].name);
sprintf(destname, "%s\\%s", ManageGraphicsDir, GameVClips[Weapons[n].fire_image_handle].name);
srcname = LocalManageGraphicsDir / GameVClips[Weapons[n].fire_image_handle].name;
destname = ManageGraphicsDir / GameVClips[Weapons[n].fire_image_handle].name;
} else {
sprintf(srcname, "%s\\%s", LocalModelsDir, Poly_models[Weapons[n].fire_image_handle].name);
sprintf(destname, "%s\\%s", NetModelsDir, Poly_models[Weapons[n].fire_image_handle].name);
srcname = LocalModelsDir / Poly_models[Weapons[n].fire_image_handle].name;
destname = NetModelsDir / Poly_models[Weapons[n].fire_image_handle].name;
}
cf_CopyFile(destname, srcname);
@ -781,7 +781,7 @@ void CWorldWeaponsDialog::OnPrevWeapon() {
}
void CWorldWeaponsDialog::OnLoadWeaponAnim() {
char filename[255], curname[255];
char filename[255];
int bm_handle;
int anim = 0;
@ -809,12 +809,13 @@ void CWorldWeaponsDialog::OnLoadWeaponAnim() {
mprintf(0, "Making a copy of this bitmap/anim locally...\n");
std::filesystem::path curname;
if (anim) {
sprintf(curname, "%s\\%s", LocalManageGraphicsDir, GameVClips[Weapons[n].hud_image_handle].name);
curname = LocalManageGraphicsDir / GameVClips[Weapons[n].hud_image_handle].name;
SaveVClip(curname, Weapons[n].hud_image_handle);
} else {
sprintf(curname, "%s\\%s", LocalManageGraphicsDir, GameBitmaps[Weapons[n].hud_image_handle].name);
curname = LocalManageGraphicsDir / GameBitmaps[Weapons[n].hud_image_handle].name;
bm_SaveFileBitmap(curname, Weapons[n].hud_image_handle);
}
@ -941,7 +942,7 @@ void CWorldWeaponsDialog::UpdateDialog() {
SendDlgItemMessage(IDC_WEAPON_PULLDOWN, CB_SELECTSTRING, 0, (LPARAM)(LPCTSTR)Weapons[n].name);
SendDlgItemMessage(IDC_FIRE_SOUND_PULLDOWN, CB_RESETCONTENT, 0, 0);
for (i = 0; i < MAX_SOUNDS; i++) {
for (int i = 0; i < MAX_SOUNDS; i++) {
if (Sounds[i].used)
SendDlgItemMessage(IDC_FIRE_SOUND_PULLDOWN, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)Sounds[i].name);
}
@ -953,7 +954,7 @@ void CWorldWeaponsDialog::UpdateDialog() {
SendDlgItemMessage(IDC_FIRE_SOUND_PULLDOWN, CB_SELECTSTRING, 0, (LPARAM)(LPCTSTR) "\0");
SendDlgItemMessage(IDC_WEAPON_BOUNCE_SOUND_COMBO, CB_RESETCONTENT, 0, 0);
for (i = 0; i < MAX_SOUNDS; i++) {
for (int i = 0; i < MAX_SOUNDS; i++) {
if (Sounds[i].used)
SendDlgItemMessage(IDC_WEAPON_BOUNCE_SOUND_COMBO, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)Sounds[i].name);
}
@ -965,7 +966,7 @@ void CWorldWeaponsDialog::UpdateDialog() {
SendDlgItemMessage(IDC_WEAPON_BOUNCE_SOUND_COMBO, CB_SELECTSTRING, 0, (LPARAM)(LPCTSTR) "\0");
SendDlgItemMessage(IDC_WEAPON_WALL_SOUND_PULLDOWN, CB_RESETCONTENT, 0, 0);
for (i = 0; i < MAX_SOUNDS; i++) {
for (int i = 0; i < MAX_SOUNDS; i++) {
if (Sounds[i].used)
SendDlgItemMessage(IDC_WEAPON_WALL_SOUND_PULLDOWN, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)Sounds[i].name);
}
@ -979,7 +980,7 @@ void CWorldWeaponsDialog::UpdateDialog() {
SendDlgItemMessage(IDC_SMOKE_PULLDOWN, CB_RESETCONTENT, 0, 0);
if (Weapons[n].flags & WF_SMOKE) {
for (i = 0; i < MAX_TEXTURES; i++) {
for (int i = 0; i < MAX_TEXTURES; i++) {
if (GameTextures[i].used)
SendDlgItemMessage(IDC_SMOKE_PULLDOWN, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)GameTextures[i].name);
}
@ -994,7 +995,7 @@ void CWorldWeaponsDialog::UpdateDialog() {
// Do scorch pulldown
SendDlgItemMessage(IDC_SCORCH_PULLDOWN, CB_RESETCONTENT, 0, 0);
SendDlgItemMessage(IDC_SCORCH_PULLDOWN, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)NULL_NAME);
for (i = 0; i < MAX_TEXTURES; i++) {
for (int i = 0; i < MAX_TEXTURES; i++) {
if (GameTextures[i].used)
SendDlgItemMessage(IDC_SCORCH_PULLDOWN, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)GameTextures[i].name);
}
@ -1008,7 +1009,7 @@ void CWorldWeaponsDialog::UpdateDialog() {
// Do icon pulldown
SendDlgItemMessage(IDC_SMALLIMG_PULLDOWN, CB_RESETCONTENT, 0, 0);
SendDlgItemMessage(IDC_SMALLIMG_PULLDOWN, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)NULL_NAME);
for (i = 0; i < MAX_TEXTURES; i++) {
for (int i = 0; i < MAX_TEXTURES; i++) {
if (GameTextures[i].used)
SendDlgItemMessage(IDC_SMALLIMG_PULLDOWN, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)GameTextures[i].name);
}
@ -1020,7 +1021,7 @@ void CWorldWeaponsDialog::UpdateDialog() {
SendDlgItemMessage(IDC_SMALLIMG_PULLDOWN, CB_SELECTSTRING, 0, (LPARAM)(LPCTSTR)NULL_NAME);
SendDlgItemMessage(IDC_EXPLODE_PULLDOWN, CB_RESETCONTENT, 0, 0);
for (i = 0; i < MAX_TEXTURES; i++) {
for (int i = 0; i < MAX_TEXTURES; i++) {
if (GameTextures[i].used)
SendDlgItemMessage(IDC_EXPLODE_PULLDOWN, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)GameTextures[i].name);
}
@ -1035,7 +1036,7 @@ void CWorldWeaponsDialog::UpdateDialog() {
// Do particle handle
SendDlgItemMessage(IDC_PARTICLE_PULLDOWN, CB_RESETCONTENT, 0, 0);
for (i = 0; i < MAX_TEXTURES; i++) {
for (int i = 0; i < MAX_TEXTURES; i++) {
if (GameTextures[i].used)
SendDlgItemMessage(IDC_PARTICLE_PULLDOWN, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)GameTextures[i].name);
}
@ -1051,7 +1052,7 @@ void CWorldWeaponsDialog::UpdateDialog() {
// Do spawn handles
SendDlgItemMessage(IDC_WEAPON_SPAWN_PULLDOWN, CB_RESETCONTENT, 0, 0);
SendDlgItemMessage(IDC_SPAWN2_PULLDOWN, CB_RESETCONTENT, 0, 0);
for (i = 0; i < MAX_WEAPONS; i++) {
for (int i = 0; i < MAX_WEAPONS; i++) {
if (Weapons[i].used) {
SendDlgItemMessage(IDC_WEAPON_SPAWN_PULLDOWN, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)Weapons[i].name);
SendDlgItemMessage(IDC_SPAWN2_PULLDOWN, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)Weapons[i].name);
@ -1076,7 +1077,7 @@ void CWorldWeaponsDialog::UpdateDialog() {
// Do spawn robot stuff
SendDlgItemMessage(IDC_SPAWN_ROBOT_PULLDOWN, CB_RESETCONTENT, 0, 0);
for (i = 0; i < MAX_OBJECT_IDS; i++) {
for (int i = 0; i < MAX_OBJECT_IDS; i++) {
if (Object_info[i].type == OBJ_ROBOT)
SendDlgItemMessage(IDC_SPAWN_ROBOT_PULLDOWN, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)Object_info[i].name);
}
@ -1412,17 +1413,17 @@ void CWorldWeaponsDialog::OnLoadWeaponDischarge() {
if (!model) {
if (!anim) {
sprintf(filename, "%s\\%s", LocalManageGraphicsDir, GameBitmaps[Weapons[n].fire_image_handle].name);
sprintf(filename, "%s\\%s", LocalManageGraphicsDir.u8string().c_str(),
GameBitmaps[Weapons[n].fire_image_handle].name);
bm_SaveFileBitmap(filename, Weapons[n].fire_image_handle);
} else {
sprintf(filename, "%s\\%s", LocalManageGraphicsDir, GameVClips[Weapons[n].fire_image_handle].name);
sprintf(filename, "%s\\%s", LocalManageGraphicsDir.u8string().c_str(),
GameVClips[Weapons[n].fire_image_handle].name);
SaveVClip(filename, Weapons[n].fire_image_handle);
}
} else {
char destname[100];
sprintf(destname, "%s\\%s", LocalModelsDir, Poly_models[Weapons[n].fire_image_handle].name);
if (stricmp(destname, filename)) // only copy if they are different
cf_CopyFile(destname, filename);
std::filesystem::path destname = LocalModelsDir / Poly_models[Weapons[n].fire_image_handle].name;
cf_CopyFile(destname, filename);
}
UpdateDialog();

View File

@ -19,7 +19,8 @@
#ifndef PSBITMAP_H
#define PSBITMAP_H
#include "pstypes.h"
#include <filesystem>
#include "cfile.h"
#ifdef __LINUX__
@ -107,7 +108,7 @@ int bm_FindBitmapName(const char *name);
int bm_SaveBitmap(CFILE *fp, int handle);
// Saves a bitmap to a file. Saves the bitmap as an OUTRAGE_TGA_TYPE.
// Returns -1 if something is wrong.
int bm_SaveFileBitmap(const char *filename, int handle);
int bm_SaveFileBitmap(const std::filesystem::path& filename, int handle);
// given a handle to a bitmap, returns its width, or -1 if handle is invalid
int bm_w(int handle, int miplevel);
// given a handle to a bitmap, returns its height, or -1 if handle is invalid

View File

@ -1,26 +1,27 @@
/*
* Descent 3
* Copyright (C) 2024 Parallax Software
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
* Descent 3
* Copyright (C) 2024 Parallax Software
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MANAGE_H
#define MANAGE_H
#include <stdio.h>
#include <cstdio>
#include <filesystem>
#include "cfile.h"
#include "bitmap.h"
#include "manage_external.h"
@ -109,27 +110,27 @@ extern int Starting_editor, Loading_locals, Loading_addon_table;
extern char LocalD3Dir[];
extern char NetD3Dir[];
extern char TableFilename[];
extern char TableLockFilename[];
extern std::filesystem::path TableLockFilename;
extern char LocalTableFilename[];
extern char LocalTempTableFilename[];
extern char LocalLevelsDir[];
extern char ManageGraphicsDir[];
extern char LocalManageGraphicsDir[];
extern char LocalModelsDir[];
extern char NetModelsDir[];
extern char LocalSoundsDir[];
extern char NetSoundsDir[];
extern char LocalRoomsDir[];
extern char NetRoomsDir[];
extern char LocalTableDir[];
extern char NetMiscDir[];
extern char LocalMiscDir[];
extern char NetMusicDir[];
extern char LocalMusicDir[];
extern std::filesystem::path ManageGraphicsDir;
extern std::filesystem::path LocalManageGraphicsDir;
extern std::filesystem::path LocalModelsDir;
extern std::filesystem::path NetModelsDir;
extern std::filesystem::path LocalSoundsDir;
extern std::filesystem::path NetSoundsDir;
extern std::filesystem::path LocalRoomsDir;
extern std::filesystem::path NetRoomsDir;
extern std::filesystem::path LocalTableDir;
extern std::filesystem::path NetMiscDir;
extern std::filesystem::path LocalMiscDir;
extern std::filesystem::path NetMusicDir;
extern std::filesystem::path LocalMusicDir;
extern char NetScriptDir[];
extern char LocalScriptDir[];
extern char NetArtDir[];
extern char LocalArtDir[];
extern std::filesystem::path NetArtDir;
extern std::filesystem::path LocalArtDir;
extern char LocalCustomGraphicsDir[];
extern char LocalCustomSoundsDir[];
@ -139,8 +140,8 @@ extern char TempTableLockFilename[];
extern char ErrorString[INFO_STRING_LEN];
extern char InfoString[INFO_STRING_LEN];
extern char TableUser[];
extern char LockerFile[];
extern char VersionFile[];
extern std::filesystem::path LockerFile;
extern std::filesystem::path VersionFile;
extern mngs_Pagelock GlobalPagelocks[];
extern mngs_track_lock GlobalTrackLocks[];
@ -236,7 +237,7 @@ int mng_RenamePage(char *oldname, char *newname, int pagetype);
// Removes a file, then renames another file to be the removed file. Get it?
// Returns 1 on success, else 0 on fail
int SwitcherooFiles(char *name, char *tempname);
int SwitcherooFiles(const char *name, char *tempname);
// Returns true if the passed in pagelock is in the LockList, else false
bool InLockList(mngs_Pagelock *pl);
@ -250,7 +251,8 @@ bool IsPrimitiveOld(char *name);
// Updates a primitive if needed
// Localname = local version of the primname (with path)
// Netname = Network version of the primname (with path)
void UpdatePrimitive(char *localname, char *netname, char *primname, int pagetype, char *pagename);
void UpdatePrimitive(const std::filesystem::path &localname, const std::filesystem::path &netname, char *primname,
int pagetype, char *pagename);
// Writes a chunk header. Writes chunk id & placeholder length. Returns chunk start pos
int StartManagePage(CFILE *ofile, uint8_t pagetype);

View File

@ -1,5 +1,5 @@
/*
* Descent 3
* Descent 3
* Copyright (C) 2024 Parallax Software
*
* This program is free software: you can redistribute it and/or modify
@ -143,6 +143,10 @@
*
* $NoKeywords: $
*/
#include <cstring>
#include <filesystem>
#include "cfile.h"
#include "manage.h"
#include "door.h"
@ -150,8 +154,6 @@
#include "mono.h"
#include "pserror.h"
#include "polymodel.h"
#include <string.h>
#include "vclip.h"
#include "ddio.h"
#include "soundload.h"
#include "soundpage.h"
@ -367,7 +369,7 @@ int mng_FindSpecificDoorPage(char *name, mngs_door_page *doorpage, int offset) {
uint8_t pagetype;
int done = 0, found = 0;
char tablename[TABLE_NAME_LEN];
std::filesystem::path tablename;
if (Loading_locals) {
infile = cfopen(LocalTableFilename, "rb");
@ -378,9 +380,9 @@ int mng_FindSpecificDoorPage(char *name, mngs_door_page *doorpage, int offset) {
int farg = FindArg("-filter");
if (farg)
strcpy(tablename, GameArgs[farg + 1]);
tablename = GameArgs[farg + 1];
else
ddio_MakePath(tablename, LocalTableDir, NET_TABLE, NULL);
tablename = LocalTableDir / NET_TABLE;
infile = cfopen(tablename, "rb");
} else {
@ -463,13 +465,8 @@ int mng_AssignDoorPageToDoor(mngs_door_page *doorpage, int n) {
#ifndef RELEASE
if (Network_up) {
char str[200];
char netstr[200];
ddio_MakePath(str, LocalModelsDir, doorpage->image_name, NULL);
ddio_MakePath(netstr, NetModelsDir, doorpage->image_name, NULL);
UpdatePrimitive(str, netstr, doorpage->image_name, PAGETYPE_DOOR, doorpointer->name);
UpdatePrimitive(LocalModelsDir / doorpage->image_name, NetModelsDir / doorpage->image_name, doorpage->image_name,
PAGETYPE_DOOR, doorpointer->name);
}
#endif

View File

@ -1,20 +1,23 @@
/*
* Descent 3
* Copyright (C) 2024 Parallax Software
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
* Descent 3
* Copyright (C) 2024 Parallax Software
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <cstring>
#include <filesystem>
#include "cfile.h"
#include "manage.h"
@ -25,8 +28,6 @@
#include "gamefilepage.h"
#include "args.h"
#include <string.h>
// gamefilepage commands that are read/written
// A command is followed by a byte count describing how many bytes
// are in the data for the command
@ -136,7 +137,7 @@ int mng_FindSpecificGamefilePage(char *name, mngs_gamefile_page *gamefilepage, i
CFILE *infile;
uint8_t pagetype;
int done = 0, found = 0;
char tablename[TABLE_NAME_LEN];
std::filesystem::path tablename;
if (Loading_locals) {
infile = cfopen(LocalTableFilename, "rb");
@ -147,9 +148,9 @@ int mng_FindSpecificGamefilePage(char *name, mngs_gamefile_page *gamefilepage, i
int farg = FindArg("-filter");
if (farg)
strcpy(tablename, GameArgs[farg + 1]);
tablename = GameArgs[farg + 1];
else
ddio_MakePath(tablename, LocalTableDir, NET_TABLE, NULL);
tablename = LocalTableDir / NET_TABLE;
infile = cfopen(tablename, "rb");
} else {
@ -226,11 +227,10 @@ int mng_AssignGamefilePageToGamefile(mngs_gamefile_page *gamefilepage, int n) {
#ifndef RELEASE
if (Network_up) {
char str[200];
char netstr[200];
ddio_MakePath(str, LocalD3Dir, "data", gamefilepointer->dir_name, gamefilepointer->name, NULL);
ddio_MakePath(netstr, NetD3Dir, "data", gamefilepointer->dir_name, gamefilepointer->name, NULL);
std::filesystem::path str =
std::filesystem::path(LocalD3Dir) / "data" / gamefilepointer->dir_name / gamefilepointer->name;
std::filesystem::path netstr =
std::filesystem::path(NetD3Dir) / "data" / gamefilepointer->dir_name / gamefilepointer->name;
UpdatePrimitive(str, netstr, gamefilepointer->name, PAGETYPE_GAMEFILE, gamefilepointer->name);

View File

@ -1,5 +1,5 @@
/*
* Descent 3
* Descent 3
* Copyright (C) 2024 Parallax Software
*
* This program is free software: you can redistribute it and/or modify
@ -351,6 +351,10 @@
*
* $NoKeywords: $
*/
#include <cstring>
#include <filesystem>
#include "cfile.h"
#include "manage.h"
#include "genericpage.h"
@ -360,7 +364,6 @@
#include "pserror.h"
#include "polymodel.h"
#include "ddio.h"
#include <string.h>
#include "robotfire.h"
#include "weapon.h"
#include "sounds.h"
@ -1755,7 +1758,7 @@ int mng_FindSpecificGenericPage(char *name, mngs_generic_page *genericpage, int
uint8_t pagetype;
int done = 0, found = 0;
int first_try = 1;
char tablename[TABLE_NAME_LEN];
std::filesystem::path tablename;
if (Loading_locals) {
infile = cfopen(LocalTableFilename, "rb");
@ -1766,9 +1769,9 @@ int mng_FindSpecificGenericPage(char *name, mngs_generic_page *genericpage, int
int farg = FindArg("-filter");
if (farg)
strcpy(tablename, GameArgs[farg + 1]);
tablename = GameArgs[farg + 1];
else
ddio_MakePath(tablename, LocalTableDir, NET_TABLE, NULL);
tablename = LocalTableDir / NET_TABLE;
infile = cfopen(tablename, "rb");
} else {
@ -1936,26 +1939,17 @@ int mng_AssignGenericPageToObjInfo(mngs_generic_page *genericpage, int n, CFILE
#ifndef RELEASE
if (Network_up) {
char str[200];
char netstr[200];
UpdatePrimitive(LocalModelsDir / genericpage->image_name, NetModelsDir / genericpage->image_name,
genericpage->image_name, PAGETYPE_GENERIC, objinfopointer->name);
ddio_MakePath(str, LocalModelsDir, genericpage->image_name, NULL);
ddio_MakePath(netstr, NetModelsDir, genericpage->image_name, NULL);
UpdatePrimitive(str, netstr, genericpage->image_name, PAGETYPE_GENERIC, objinfopointer->name);
if (stricmp(genericpage->med_image_name, "INVALID NAME") && genericpage->med_image_name[0] != 0) {
ddio_MakePath(str, LocalModelsDir, genericpage->med_image_name, NULL);
ddio_MakePath(netstr, NetModelsDir, genericpage->med_image_name, NULL);
UpdatePrimitive(str, netstr, genericpage->med_image_name, PAGETYPE_GENERIC, objinfopointer->name);
if (stricmp(genericpage->med_image_name, "INVALID NAME") != 0 && genericpage->med_image_name[0] != 0) {
UpdatePrimitive(LocalModelsDir / genericpage->med_image_name, NetModelsDir / genericpage->med_image_name,
genericpage->med_image_name, PAGETYPE_GENERIC, objinfopointer->name);
}
if (stricmp(genericpage->lo_image_name, "INVALID NAME") && genericpage->lo_image_name[0] != 0) {
ddio_MakePath(str, LocalModelsDir, genericpage->lo_image_name, NULL);
ddio_MakePath(netstr, NetModelsDir, genericpage->lo_image_name, NULL);
UpdatePrimitive(str, netstr, genericpage->lo_image_name, PAGETYPE_GENERIC, objinfopointer->name);
if (stricmp(genericpage->lo_image_name, "INVALID NAME") != 0 && genericpage->lo_image_name[0] != 0) {
UpdatePrimitive(LocalModelsDir / genericpage->lo_image_name, NetModelsDir / genericpage->lo_image_name,
genericpage->lo_image_name, PAGETYPE_GENERIC, objinfopointer->name);
}
}
#endif
@ -2001,8 +1995,7 @@ int mng_AssignGenericPageToObjInfo(mngs_generic_page *genericpage, int n, CFILE
int sound_handle = mng_GetGuaranteedSoundPage(genericpage->sound_name[i]);
if (sound_handle < 0) {
mprintf(0, "Couldn't load sound file '%s' in AssignPowPage %s...\n",
genericpage->sound_name[i],
mprintf(0, "Couldn't load sound file '%s' in AssignPowPage %s...\n", genericpage->sound_name[i],
genericpage->objinfo_struct.name);
objinfopointer->sounds[i] = SOUND_NONE_INDEX;
} else
@ -2036,8 +2029,7 @@ int mng_AssignGenericPageToObjInfo(mngs_generic_page *genericpage, int n, CFILE
int sound_handle = mng_GetGuaranteedSoundPage(genericpage->ai_sound_name[i]);
if (sound_handle < 0) {
mprintf(0, "Couldn't load ai sound file '%s' in AssignPowPage %s...\n",
genericpage->ai_sound_name[i],
mprintf(0, "Couldn't load ai sound file '%s' in AssignPowPage %s...\n", genericpage->ai_sound_name[i],
genericpage->objinfo_struct.name);
objinfopointer->ai_info->sound[i] = SOUND_NONE_INDEX;
} else
@ -2055,8 +2047,7 @@ int mng_AssignGenericPageToObjInfo(mngs_generic_page *genericpage, int n, CFILE
int weapon_handle = mng_GetGuaranteedWeaponPage(genericpage->weapon_name[i][j]);
if (weapon_handle < 0) {
mprintf(0, "Couldn't load weapon file '%s' in AssignPowPage %s...\n",
genericpage->weapon_name[i][j],
mprintf(0, "Couldn't load weapon file '%s' in AssignPowPage %s...\n", genericpage->weapon_name[i][j],
genericpage->objinfo_struct.name);
objinfopointer->static_wb[i].gp_weapon_index[j] = LASER_INDEX;
} else
@ -2074,8 +2065,7 @@ int mng_AssignGenericPageToObjInfo(mngs_generic_page *genericpage, int n, CFILE
if (fire_sound_handle < 0) {
mprintf(0, "Couldn't load fire sound file '%s' in AssignPowPage %s...\n",
genericpage->fire_sound_name[i][j],
genericpage->objinfo_struct.name);
genericpage->fire_sound_name[i][j], genericpage->objinfo_struct.name);
objinfopointer->static_wb[i].fm_fire_sound_index[j] = SOUND_NONE_INDEX;
} else
objinfopointer->static_wb[i].fm_fire_sound_index[j] = fire_sound_handle;
@ -2094,8 +2084,7 @@ int mng_AssignGenericPageToObjInfo(mngs_generic_page *genericpage, int n, CFILE
if (anim_sound_handle < 0) {
mprintf(0, "Couldn't load anim sound file '%s' in AssignPowPage %s...\n",
genericpage->anim_sound_name[i][j],
genericpage->objinfo_struct.name);
genericpage->anim_sound_name[i][j], genericpage->objinfo_struct.name);
objinfopointer->anim[i].elem[j].anim_sound_index = SOUND_NONE_INDEX;
} else
objinfopointer->anim[i].elem[j].anim_sound_index = anim_sound_handle;

View File

@ -1,5 +1,5 @@
/*
* Descent 3
* Descent 3
* Copyright (C) 2024 Parallax Software
*
* This program is free software: you can redistribute it and/or modify
@ -434,12 +434,13 @@
* $NoKeywords: $
*/
#include <cerrno>
#include <cstdarg>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <filesystem>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#if defined(__LINUX__)
#include "linux_fix.h"
#endif
@ -473,26 +474,27 @@ void mng_WriteNewUnknownPage(CFILE *outfile);
// This is for levels
char LocalLevelsDir[TABLE_NAME_LEN];
// This is for pages
char TableLockFilename[TABLE_NAME_LEN], TableFilename[TABLE_NAME_LEN];
std::filesystem::path TableLockFilename;
char TableFilename[TABLE_NAME_LEN];
char TempTableLockFilename[TABLE_NAME_LEN], TempTableFilename[TABLE_NAME_LEN];
char LocalTableFilename[TABLE_NAME_LEN], LocalTempTableFilename[TABLE_NAME_LEN];
char BackupTableFilename[TABLE_NAME_LEN], BackupLockFilename[TABLE_NAME_LEN];
char ManageGraphicsDir[TABLE_NAME_LEN], LocalManageGraphicsDir[TABLE_NAME_LEN];
char LocalModelsDir[TABLE_NAME_LEN], NetModelsDir[TABLE_NAME_LEN];
char LocalSoundsDir[TABLE_NAME_LEN], NetSoundsDir[TABLE_NAME_LEN];
char LocalRoomsDir[TABLE_NAME_LEN], NetRoomsDir[TABLE_NAME_LEN];
char LocalBriefingDir[TABLE_NAME_LEN], NetBriefingDir[TABLE_NAME_LEN];
std::filesystem::path ManageGraphicsDir, LocalManageGraphicsDir;
std::filesystem::path LocalModelsDir, NetModelsDir;
std::filesystem::path LocalSoundsDir, NetSoundsDir;
std::filesystem::path LocalRoomsDir, NetRoomsDir;
std::filesystem::path LocalBriefingDir, NetBriefingDir;
char LocalScriptDir[TABLE_NAME_LEN], NetScriptDir[TABLE_NAME_LEN];
char LocalMiscDir[TABLE_NAME_LEN], NetMiscDir[TABLE_NAME_LEN];
char LocalArtDir[TABLE_NAME_LEN], NetArtDir[TABLE_NAME_LEN];
char LocalMusicDir[TABLE_NAME_LEN], NetMusicDir[TABLE_NAME_LEN];
char LocalVoiceDir[TABLE_NAME_LEN], NetVoiceDir[TABLE_NAME_LEN];
char NetTableDir[TABLE_NAME_LEN], LocalTableDir[TABLE_NAME_LEN];
std::filesystem::path LocalMiscDir, NetMiscDir;
std::filesystem::path LocalArtDir, NetArtDir;
std::filesystem::path LocalMusicDir, NetMusicDir;
std::filesystem::path LocalVoiceDir, NetVoiceDir;
std::filesystem::path NetTableDir, LocalTableDir;
char LocalD3Dir[TABLE_NAME_LEN], NetD3Dir[TABLE_NAME_LEN];
char LocalCustomGraphicsDir[TABLE_NAME_LEN];
char LocalCustomSoundsDir[TABLE_NAME_LEN];
char LockerFile[TABLE_NAME_LEN];
char VersionFile[TABLE_NAME_LEN];
std::filesystem::path LockerFile;
std::filesystem::path VersionFile;
char TableUser[TABLE_NAME_LEN];
char ErrorString[INFO_STRING_LEN], InfoString[INFO_STRING_LEN];
mngs_track_lock GlobalTrackLocks[MAX_TRACKLOCKS];
@ -521,7 +523,7 @@ struct old_file {
int Num_old_files = 0;
old_file *OldFiles;
const char *PageNames[] = {"Unknown", "Texture", "Weapon", "Robot", "Powerup", "Door",
"Player ship", "Sound", "Megacell", "Files", "Generic objects"};
"Player ship", "Sound", "Megacell", "Files", "Generic objects"};
#ifndef RELEASE
int Network_up = 1;
int Stand_alone = 0;
@ -530,10 +532,10 @@ int Network_up = 0;
int Stand_alone = 1;
#endif
void mng_BackupTableFile();
// returns 1 if network is up, 0 if down
int mng_IsNetworkUp() {
char dir[100];
int ret;
if (Stand_alone)
return 0;
@ -544,8 +546,9 @@ int mng_IsNetworkUp() {
return 0;
ddio_MakePath(dir, net_dir, "data", NULL);
ret = ddio_CreateDir(dir);
if (!ret) {
std::error_code ec;
std::filesystem::create_directories(dir, ec);
if (!ec) {
char old_dir[100];
ddio_GetWorkingDir(old_dir, 100);
if (!ddio_SetWorkingDir(dir))
@ -677,40 +680,42 @@ int mng_InitLocalTables() {
// Make the CFILE system first look at our local directories. If the goods aren't
// found there, try out on the network
ddio_MakePath(LocalTableDir, LocalD3Dir, "data", "tables", NULL);
ddio_MakePath(LocalManageGraphicsDir, LocalD3Dir, "data", "graphics", NULL);
ddio_MakePath(LocalModelsDir, LocalD3Dir, "data", "models", NULL);
ddio_MakePath(LocalSoundsDir, LocalD3Dir, "data", "sounds", NULL);
// TODO: temp variable until LocalD3Dir will be std::fs::path
std::filesystem::path localdir = std::filesystem::path(LocalD3Dir);
LocalTableDir = localdir / "data" / "tables";
LocalManageGraphicsDir = localdir / "data" / "graphics";
LocalModelsDir = localdir / "data" / "models";
LocalSoundsDir = localdir / "data" / "sounds";
ddio_MakePath(LocalCustomSoundsDir, LocalD3Dir, "custom", "sounds", NULL);
ddio_MakePath(LocalCustomGraphicsDir, LocalD3Dir, "custom", "graphics", NULL);
ddio_MakePath(LocalRoomsDir, LocalD3Dir, "data", "rooms", NULL);
ddio_MakePath(LocalBriefingDir, LocalD3Dir, "data", "briefings", NULL);
LocalRoomsDir = localdir / "data" / "rooms";
LocalBriefingDir = localdir / "data" / "briefings";
ddio_MakePath(LocalScriptDir, LocalD3Dir, "data", "scripts", NULL);
ddio_MakePath(LocalMiscDir, LocalD3Dir, "data", "misc", NULL);
ddio_MakePath(LocalArtDir, LocalD3Dir, "data", "art", NULL);
ddio_MakePath(LocalMusicDir, LocalD3Dir, "data", "music", NULL);
ddio_MakePath(LocalVoiceDir, LocalD3Dir, "data", "voice", NULL);
LocalMiscDir = localdir / "data" / "misc";
LocalArtDir = localdir / "data" / "art";
LocalMusicDir = localdir / "data" / "music";
LocalVoiceDir = localdir / "data" / "voice";
ddio_MakePath(LocalLevelsDir, LocalD3Dir, "data", "levels", NULL);
cf_SetSearchPath(LocalD3Dir, NULL);
cf_SetSearchPath(LocalD3Dir);
#ifndef RELEASE
cf_SetSearchPath(LocalLevelsDir, NULL);
cf_SetSearchPath(LocalTableDir, NULL); // Local table directory
cf_SetSearchPath(LocalLevelsDir);
cf_SetSearchPath(LocalTableDir); // Local table directory
cf_SetSearchPath(LocalManageGraphicsDir, NULL);
cf_SetSearchPath(LocalModelsDir, NULL);
cf_SetSearchPath(LocalSoundsDir, NULL);
cf_SetSearchPath(LocalRoomsDir, NULL);
cf_SetSearchPath(LocalBriefingDir, NULL);
cf_SetSearchPath(LocalScriptDir, "cpp", "dll", "def", "msg", "so", "msl", "dylib", NULL);
cf_SetSearchPath(LocalMiscDir, NULL);
cf_SetSearchPath(LocalArtDir, NULL);
cf_SetSearchPath(LocalMusicDir, NULL);
cf_SetSearchPath(LocalVoiceDir, NULL);
cf_SetSearchPath(LocalManageGraphicsDir);
cf_SetSearchPath(LocalModelsDir);
cf_SetSearchPath(LocalSoundsDir);
cf_SetSearchPath(LocalRoomsDir);
cf_SetSearchPath(LocalBriefingDir);
cf_SetSearchPath(LocalScriptDir, {".cpp", ".dll", ".def", ".msg", ".so", ".msl", ".dylib"});
cf_SetSearchPath(LocalMiscDir);
cf_SetSearchPath(LocalArtDir);
cf_SetSearchPath(LocalMusicDir);
cf_SetSearchPath(LocalVoiceDir);
#endif
if (Network_up) {
ddio_MakePath(LocalTableFilename, LocalTableDir, LOCAL_TABLE, NULL);
ddio_MakePath(LocalTempTableFilename, LocalTableDir, TEMP_LOCAL_TABLE, NULL);
ddio_MakePath(LocalTableFilename, LocalTableDir.u8string().c_str(), LOCAL_TABLE, NULL);
ddio_MakePath(LocalTempTableFilename, LocalTableDir.u8string().c_str(), TEMP_LOCAL_TABLE, NULL);
} else {
strcpy(LocalTableFilename, LOCAL_TABLE);
strcpy(LocalTempTableFilename, TEMP_LOCAL_TABLE);
@ -727,33 +732,36 @@ int mng_InitNetTables() {
strcpy(NetD3Dir, dir);
mprintf(1, "Net dir:%s\n", NetD3Dir);
ddio_MakePath(NetModelsDir, NetD3Dir, "data", "models", NULL);
ddio_MakePath(NetSoundsDir, NetD3Dir, "data", "sounds", NULL);
ddio_MakePath(NetRoomsDir, NetD3Dir, "data", "rooms", NULL);
ddio_MakePath(NetBriefingDir, NetD3Dir, "data", "briefings", NULL);
ddio_MakePath(NetScriptDir, NetD3Dir, "data", "scripts", NULL);
ddio_MakePath(NetMiscDir, NetD3Dir, "data", "misc", NULL);
ddio_MakePath(ManageGraphicsDir, NetD3Dir, "data", "graphics", NULL);
ddio_MakePath(NetTableDir, NetD3Dir, "data", "tables", NULL);
ddio_MakePath(NetArtDir, NetD3Dir, "data", "art", NULL);
ddio_MakePath(NetMusicDir, NetD3Dir, "data", "music", NULL);
ddio_MakePath(NetVoiceDir, NetD3Dir, "data", "voice", NULL);
ddio_MakePath(TableLockFilename, NetTableDir, "table.lok", NULL);
ddio_MakePath(BackupLockFilename, NetTableDir, "tablelok.bak", NULL);
ddio_MakePath(BackupTableFilename, NetTableDir, "table.bak", NULL);
ddio_MakePath(TableFilename, NetTableDir, NET_TABLE, NULL);
ddio_MakePath(TempTableLockFilename, NetTableDir, "lock.tmp", NULL);
ddio_MakePath(TempTableFilename, NetTableDir, TEMP_NET_TABLE, NULL);
ddio_MakePath(LockerFile, NetTableDir, "locker", NULL);
ddio_MakePath(VersionFile, NetTableDir, "TableVersion", NULL);
// TODO: temp variable until NetD3Dir will be std::fs::path
std::filesystem::path netdir = std::filesystem::path(NetD3Dir);
cf_SetSearchPath(ManageGraphicsDir, NULL);
cf_SetSearchPath(NetModelsDir, NULL);
cf_SetSearchPath(NetSoundsDir, NULL);
cf_SetSearchPath(NetRoomsDir, NULL);
cf_SetSearchPath(NetMiscDir, NULL);
cf_SetSearchPath(NetMusicDir, NULL);
cf_SetSearchPath(NetVoiceDir, NULL);
NetModelsDir = netdir / "data" / "models";
NetSoundsDir = netdir / "data" / "sounds";
NetRoomsDir = netdir / "data" / "rooms";
NetBriefingDir = netdir / "data" / "briefings";
ddio_MakePath(NetScriptDir, NetD3Dir, "data", "scripts", NULL);
NetMiscDir = netdir / "data" / "misc";
ManageGraphicsDir = netdir / "data" / "graphics";
NetTableDir = netdir / "data" / "tables";
NetArtDir = netdir / "data" / "art";
NetMusicDir = netdir / "data" / "music";
NetVoiceDir = netdir / "data" / "voice";
TableLockFilename = NetTableDir / "table.lok";
ddio_MakePath(BackupLockFilename, NetTableDir.u8string().c_str(), "tablelok.bak", NULL);
ddio_MakePath(BackupTableFilename, NetTableDir.u8string().c_str(), "table.bak", NULL);
ddio_MakePath(TableFilename, NetTableDir.u8string().c_str(), NET_TABLE, NULL);
ddio_MakePath(TempTableLockFilename, NetTableDir.u8string().c_str(), "lock.tmp", NULL);
ddio_MakePath(TempTableFilename, NetTableDir.u8string().c_str(), TEMP_NET_TABLE, NULL);
LockerFile = NetTableDir / "locker";
VersionFile = NetTableDir / "TableVersion";
cf_SetSearchPath(ManageGraphicsDir);
cf_SetSearchPath(NetModelsDir);
cf_SetSearchPath(NetSoundsDir);
cf_SetSearchPath(NetRoomsDir);
cf_SetSearchPath(NetMiscDir);
cf_SetSearchPath(NetMusicDir);
cf_SetSearchPath(NetVoiceDir);
return 1;
}
void mng_CheckToCreateNetTables() {
@ -804,103 +812,73 @@ void mng_CheckToCreateLocalTables() {
}
// Creates directories if needed
void mng_InitLocalDirectories() {
char dir[255];
ddio_MakePath(dir, LocalD3Dir, "custom", NULL);
ddio_CreateDir(dir);
ddio_MakePath(dir, LocalD3Dir, "custom", "graphics", NULL);
ddio_CreateDir(dir);
ddio_MakePath(dir, LocalD3Dir, "custom", "sounds", NULL);
ddio_CreateDir(dir);
ddio_MakePath(dir, LocalD3Dir, "custom", "cache", NULL);
ddio_CreateDir(dir);
ddio_MakePath(dir, LocalD3Dir, "custom", "settings", NULL);
ddio_CreateDir(dir);
cf_SetSearchPath(LocalCustomGraphicsDir, NULL);
cf_SetSearchPath(LocalCustomSoundsDir, NULL);
std::filesystem::path dir = LocalD3Dir;
std::error_code ec;
std::filesystem::create_directories(dir / "custom", ec);
std::filesystem::create_directories(dir / "custom" / "graphics", ec);
std::filesystem::create_directories(dir / "custom" / "sounds", ec);
std::filesystem::create_directories(dir / "custom" / "cache", ec);
std::filesystem::create_directories(dir / "custom" / "settings", ec);
cf_SetSearchPath(LocalCustomGraphicsDir);
cf_SetSearchPath(LocalCustomSoundsDir);
if (Network_up) {
ddio_MakePath(dir, LocalD3Dir, "data", NULL);
ddio_CreateDir(dir);
ddio_MakePath(dir, LocalD3Dir, "data", "tables", NULL);
ddio_CreateDir(dir);
ddio_MakePath(dir, LocalD3Dir, "data", "graphics", NULL);
ddio_CreateDir(dir);
ddio_MakePath(dir, LocalD3Dir, "data", "sounds", NULL);
ddio_CreateDir(dir);
ddio_MakePath(dir, LocalD3Dir, "data", "rooms", NULL);
ddio_CreateDir(dir);
ddio_MakePath(dir, LocalD3Dir, "data", "levels", NULL);
ddio_CreateDir(dir);
ddio_MakePath(dir, LocalD3Dir, "data", "models", NULL);
ddio_CreateDir(dir);
ddio_MakePath(dir, LocalD3Dir, "data", "briefings", NULL);
ddio_CreateDir(dir);
ddio_MakePath(dir, LocalD3Dir, "data", "scripts", NULL);
ddio_CreateDir(dir);
ddio_MakePath(dir, LocalD3Dir, "data", "misc", NULL);
ddio_CreateDir(dir);
ddio_MakePath(dir, LocalD3Dir, "data", "art", NULL);
ddio_CreateDir(dir);
ddio_MakePath(dir, LocalD3Dir, "data", "music", NULL);
ddio_CreateDir(dir);
ddio_MakePath(dir, LocalD3Dir, "data", "voice", NULL);
ddio_CreateDir(dir);
std::filesystem::create_directories(dir / "data", ec);
std::filesystem::create_directories(dir / "data" / "tables", ec);
std::filesystem::create_directories(dir / "data" / "graphics", ec);
std::filesystem::create_directories(dir / "data" / "sounds", ec);
std::filesystem::create_directories(dir / "data" / "rooms", ec);
std::filesystem::create_directories(dir / "data" / "levels", ec);
std::filesystem::create_directories(dir / "data" / "models", ec);
std::filesystem::create_directories(dir / "data" / "briefings", ec);
std::filesystem::create_directories(dir / "data" / "scripts", ec);
std::filesystem::create_directories(dir / "data" / "misc", ec);
std::filesystem::create_directories(dir / "data" / "art", ec);
std::filesystem::create_directories(dir / "data" / "music", ec);
std::filesystem::create_directories(dir / "data" / "voice", ec);
}
}
void mng_InitNetDirectories() {
char dir[255];
std::filesystem::path dir = NetD3Dir;
std::error_code ec;
if (Stand_alone)
return;
ddio_MakePath(dir, NetD3Dir, "data", NULL);
ddio_CreateDir(dir);
ddio_MakePath(dir, NetD3Dir, "data", "tables", NULL);
ddio_CreateDir(dir);
ddio_MakePath(dir, NetD3Dir, "data", "graphics", NULL);
ddio_CreateDir(dir);
ddio_MakePath(dir, NetD3Dir, "data", "sounds", NULL);
ddio_CreateDir(dir);
ddio_MakePath(dir, NetD3Dir, "data", "rooms", NULL);
ddio_CreateDir(dir);
ddio_MakePath(dir, NetD3Dir, "data", "levels", NULL);
ddio_CreateDir(dir);
ddio_MakePath(dir, NetD3Dir, "data", "models", NULL);
ddio_CreateDir(dir);
ddio_MakePath(dir, NetD3Dir, "data", "briefings", NULL);
ddio_CreateDir(dir);
ddio_MakePath(dir, NetD3Dir, "data", "scripts", NULL);
ddio_CreateDir(dir);
ddio_MakePath(dir, NetD3Dir, "data", "misc", NULL);
ddio_CreateDir(dir);
ddio_MakePath(dir, NetD3Dir, "data", "art", NULL);
ddio_CreateDir(dir);
ddio_MakePath(dir, NetD3Dir, "data", "music", NULL);
ddio_CreateDir(dir);
ddio_MakePath(dir, NetD3Dir, "data", "voice", NULL);
ddio_CreateDir(dir);
std::filesystem::create_directories(dir / "data", ec);
std::filesystem::create_directories(dir / "data" / "tables", ec);
std::filesystem::create_directories(dir / "data" / "graphics", ec);
std::filesystem::create_directories(dir / "data" / "sounds", ec);
std::filesystem::create_directories(dir / "data" / "rooms", ec);
std::filesystem::create_directories(dir / "data" / "levels", ec);
std::filesystem::create_directories(dir / "data" / "models", ec);
std::filesystem::create_directories(dir / "data" / "briefings", ec);
std::filesystem::create_directories(dir / "data" / "scripts", ec);
std::filesystem::create_directories(dir / "data" / "misc", ec);
std::filesystem::create_directories(dir / "data" / "art", ec);
std::filesystem::create_directories(dir / "data" / "music", ec);
std::filesystem::create_directories(dir / "data" / "voice", ec);
}
extern int TableVersionCurrent();
#if !defined(WIN32)
void mng_BackupTableFile() {}
#else
void mng_BackupTableFile() {
char str[200];
Fast_load_trick = 0;
if (!TableVersionCurrent()) {
Error("You must do a source update and recompile. The data on the network is newer that your sourcecode.");
return;
}
ddio_MakePath(str, LocalTableDir, NET_TABLE, NULL);
std::filesystem::path str = LocalTableDir / NET_TABLE;
if (!cfexist(str)) {
TableTimeThreshold.dwHighDateTime = 0;
TableTimeThreshold.dwLowDateTime = 0;
} else {
WIN32_FIND_DATA filedata;
HANDLE filehandle = FindFirstFile(str, &filedata);
HANDLE filehandle = FindFirstFile(str.u8string().c_str(), &filedata);
if (filehandle == INVALID_HANDLE_VALUE) {
Error("Couldn't open net table file for some reason!");
return;
@ -914,7 +892,7 @@ void mng_BackupTableFile() {
if (!cf_CopyFile(str, TableFilename, 1))
Error("There was an error making a backup copy of the table file.\n");
ddio_MakePath(str, LocalTableDir, "tablelok.loc", NULL);
str = LocalTableDir / "tablelok.loc";
if (!cf_CopyFile(str, TableLockFilename, 1))
Error("There was an error making a backup copy of the locker table file.\n");
} else {
@ -1234,7 +1212,7 @@ int mng_RenamePage(char *oldname, char *newname, int pagetype) {
int mng_LoadNetPages(int show_progress) {
CFILE *infile;
uint8_t pagetype;
char tablename[TABLE_NAME_LEN];
std::filesystem::path tablename;
float start_time;
int n_pages = 0;
int total_bytes;
@ -1251,9 +1229,9 @@ int mng_LoadNetPages(int show_progress) {
if (Network_up) {
int farg = FindArg("-filter");
if (farg)
strcpy(tablename, GameArgs[farg + 1]);
tablename = GameArgs[farg + 1];
else {
ddio_MakePath(tablename, LocalTableDir, NET_TABLE, NULL);
tablename = LocalTableDir / NET_TABLE;
}
infile = cfopen(tablename, "rb");
} else
@ -1484,7 +1462,7 @@ int mng_LoadLocalPages() {
#define MAX_TRIES 10000
// Removes a file, then renames another file to be the removed file. Get it?
// Returns 1 on success, else 0 on fail
int SwitcherooFiles(char *name, char *tempname) {
int SwitcherooFiles(const char *name, char *tempname) {
/*// If we're changing the net table file, make a backup first!
if ((!stricmp (name,TableFilename)))
{
@ -1635,7 +1613,7 @@ void mng_TransferPages() {
snprintf(ErrorString, sizeof(ErrorString), "There was a problem deleting the temp file - errno %d", errno);
goto done;
}
if (rename(TempTableLockFilename, TableLockFilename)) {
if (rename(TempTableLockFilename, TableLockFilename.u8string().c_str())) {
snprintf(ErrorString, sizeof(ErrorString), "There was a problem renaming the temp file - errno %d", errno);
goto done;
@ -1919,31 +1897,29 @@ bool InLockList(mngs_Pagelock *pl) {
return false;
}
// Given a filename, returns the type of primitive it is
int GetPrimType(char *name) {
char ext[10];
char tname[_MAX_PATH];
int GetPrimType(const std::filesystem::path &name) {
int primtype;
ddio_SplitPath(name, tname, tname, ext);
if (!stricmp("oof", ext))
std::filesystem::path ext = name.extension();
if (!stricmp(".oof", ext.u8string().c_str()))
primtype = PRIMTYPE_OOF;
else if (!stricmp("ogf", ext))
else if (!stricmp(".ogf", ext.u8string().c_str()))
primtype = PRIMTYPE_OGF;
else if (!stricmp("oaf", ext))
else if (!stricmp(".oaf", ext.u8string().c_str()))
primtype = PRIMTYPE_OAF;
else if (!stricmp("wav", ext))
else if (!stricmp(".wav", ext.u8string().c_str()))
primtype = PRIMTYPE_WAV;
else
primtype = PRIMTYPE_FILE;
return primtype;
}
#if defined(WIN32)
// Builds a list of old files in a path
void BuildOldFilesForDirectory(char *path, FILETIME threshold) {
void BuildOldFilesForDirectory(const std::filesystem::path& path, FILETIME threshold) {
HANDLE filehandle;
WIN32_FIND_DATA filedata;
char newpath[_MAX_PATH];
ddio_MakePath(newpath, path, "*.*", NULL);
filehandle = FindFirstFile(newpath, &filedata);
std::filesystem::path newpath = path / "*.*";
filehandle = FindFirstFile(newpath.u8string().c_str(), &filedata);
bool go_ahead = true;
if (filehandle == INVALID_HANDLE_VALUE)
go_ahead = false;
@ -1976,6 +1952,7 @@ void BuildOldFilesForDirectory(char *path, FILETIME threshold) {
if (filehandle != INVALID_HANDLE_VALUE)
FindClose(filehandle);
}
// Builds a list of old files so we know which ones to update
// Searches through all our netdirectories for old files
void BuildOldFileList(FILETIME threshold) {
@ -1997,6 +1974,7 @@ void BuildOldFileList(FILETIME threshold) {
mprintf(0, "Found %d old files.\n", Num_old_files);
}
#endif
// Returns true if the passed in primitive is old (ie needs to be updated from the network)
bool IsPrimitiveOld(char *name) {
int primtype = GetPrimType(name);
@ -2007,10 +1985,12 @@ bool IsPrimitiveOld(char *name) {
return false;
}
// Updates a primitive if needed
// Localname = local version of the primname (with path)
// Netname = Network version of the primname (with path)
void UpdatePrimitive(char *localname, char *netname, char *primname, int pagetype, char *pagename) {
void UpdatePrimitive(const std::filesystem::path &localname, const std::filesystem::path &netname, char *primname,
int pagetype, char *pagename) {
bool update = false;
if (Starting_editor && !Use_old_update_method) {
if (IsPrimitiveOld(primname))
@ -2923,8 +2903,7 @@ void mng_CompileAddonPages(void) {
continue;
// this is it!
mprintf(0, "***Compiling: %s[%s] to %d\n",
AddOnDataTables[tf].Addon_tracklocks[i].name,
mprintf(0, "***Compiling: %s[%s] to %d\n", AddOnDataTables[tf].Addon_tracklocks[i].name,
(curr_tablefile == 1) ? TableFilename : AddOnDataTables[curr_tablefile - 2].AddOnTableFilename,
page_pos);
ASSERT(AddOnDataTables[tf].Addon_tracklocks[i].stack_filepos == 0);

View File

@ -1,5 +1,5 @@
/*
* Descent 3
* Descent 3
* Copyright (C) 2024 Parallax Software
*
* This program is free software: you can redistribute it and/or modify
@ -175,20 +175,21 @@
* $NoKeywords: $
*/
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <cerrno>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <filesystem>
#include "cfile.h"
#include "manage.h"
#include "pstypes.h"
#include "pserror.h"
#include "mono.h"
#include "string.h"
#include "mem.h"
#include "ddio.h"
#ifndef RELEASE
#include <time.h>
#include <ctime>
#endif
#define CURRENT_TABLE_VERSION 22
@ -524,16 +525,15 @@ int mng_ReplacePagelock(char *name, mngs_Pagelock *pl) {
cfclose(infile);
cfclose(outfile);
if (!SwitcherooFiles(TableLockFilename, TempTableLockFilename)) {
if (!SwitcherooFiles(TableLockFilename.u8string().c_str(), TempTableLockFilename)) {
Int3();
return 0;
}
// Log this change
#ifndef RELEASE
char pathstr[255];
ddio_MakePath(pathstr, NetD3Dir, "TableLog", NULL);
FILE *logfile = fopen(pathstr, "at");
std::filesystem::path pathstr = std::filesystem::path(NetD3Dir) / "TableLog";
FILE *logfile = fopen(pathstr.u8string().c_str(), "at");
if (logfile) {
char str[255 + 32];
char date[255];
@ -591,7 +591,7 @@ int mng_DeletePagelock(char *name, int pagetype) {
snprintf(ErrorString, sizeof(ErrorString), "There was a problem deleting the temp file - errno %d", errno);
return (0);
}
if (rename(TempTableLockFilename, TableLockFilename)) {
if (rename(TempTableLockFilename, TableLockFilename.u8string().c_str())) {
snprintf(ErrorString, sizeof(ErrorString), "There was a problem renaming the temp file - errno %d", errno);
return (0);
@ -645,7 +645,7 @@ int mng_DeletePagelockSeries(char *names[], int num, int pagetype) {
snprintf(ErrorString, sizeof(ErrorString), "There was a problem deleting the temp file - errno %d", errno);
return (0);
}
if (rename(TempTableLockFilename, TableLockFilename)) {
if (rename(TempTableLockFilename, TableLockFilename.u8string().c_str())) {
snprintf(ErrorString, sizeof(ErrorString), "There was a problem renaming the temp file - errno %d", errno);
return (0);
@ -782,7 +782,7 @@ int mng_UnlockPagelockSeries(const char *names[], int *pagetypes, int num) {
snprintf(ErrorString, sizeof(ErrorString), "There was a problem deleting the temp file - errno %d", errno);
return (0);
}
if (rename(TempTableLockFilename, TableLockFilename)) {
if (rename(TempTableLockFilename, TableLockFilename.u8string().c_str())) {
snprintf(ErrorString, sizeof(ErrorString), "There was a problem renaming the temp file - errno %d", errno);
return (0);

View File

@ -1,5 +1,5 @@
/*
* Descent 3
* Descent 3
* Copyright (C) 2024 Parallax Software
*
* This program is free software: you can redistribute it and/or modify
@ -197,6 +197,10 @@
*
* $NoKeywords: $
*/
#include <cstring>
#include <filesystem>
#include "cfile.h"
#include "manage.h"
#include "ship.h"
@ -207,7 +211,6 @@
#include "ddio.h"
#include "robotfire.h"
#include "weaponpage.h"
#include <string.h>
#include "soundload.h"
#include "sounds.h"
#include "soundpage.h"
@ -837,7 +840,7 @@ int mng_FindSpecificShipPage(char *name, mngs_ship_page *shippage, int offset) {
uint8_t pagetype;
int done = 0, found = 0;
int first_try = 1;
char tablename[TABLE_NAME_LEN];
std::filesystem::path tablename;
if (Loading_locals) {
infile = cfopen(LocalTableFilename, "rb");
@ -848,9 +851,9 @@ int mng_FindSpecificShipPage(char *name, mngs_ship_page *shippage, int offset) {
int farg = FindArg("-filter");
if (farg)
strcpy(tablename, GameArgs[farg + 1]);
tablename = GameArgs[farg + 1];
else
ddio_MakePath(tablename, LocalTableDir, NET_TABLE, NULL);
tablename = LocalTableDir / NET_TABLE;
infile = cfopen(tablename, "rb");
} else {
@ -943,33 +946,22 @@ int mng_AssignShipPageToShip(mngs_ship_page *shippage, int n, CFILE *infile) {
#ifndef RELEASE
if (Network_up) {
char str[200];
char netstr[200];
UpdatePrimitive(LocalModelsDir / shippage->image_name, NetModelsDir / shippage->image_name, shippage->image_name,
PAGETYPE_SHIP, shippointer->name);
ddio_MakePath(str, LocalModelsDir, shippage->image_name, NULL);
ddio_MakePath(netstr, NetModelsDir, shippage->image_name, NULL);
UpdatePrimitive(str, netstr, shippage->image_name, PAGETYPE_SHIP, shippointer->name);
if (stricmp("INVALID IMAGE NAME", shippage->dying_image_name) && shippage->dying_image_name[0] != 0) {
ddio_MakePath(str, LocalModelsDir, shippage->dying_image_name, NULL);
ddio_MakePath(netstr, NetModelsDir, shippage->dying_image_name, NULL);
UpdatePrimitive(str, netstr, shippage->dying_image_name, PAGETYPE_SHIP, shippointer->name);
if (stricmp("INVALID IMAGE NAME", shippage->dying_image_name) != 0 && shippage->dying_image_name[0] != 0) {
UpdatePrimitive(LocalModelsDir / shippage->dying_image_name, NetModelsDir / shippage->dying_image_name,
shippage->dying_image_name, PAGETYPE_SHIP, shippointer->name);
}
if (shippage->med_image_name[0] != 0) {
ddio_MakePath(str, LocalModelsDir, shippage->med_image_name, NULL);
ddio_MakePath(netstr, NetModelsDir, shippage->med_image_name, NULL);
UpdatePrimitive(str, netstr, shippage->med_image_name, PAGETYPE_SHIP, shippointer->name);
UpdatePrimitive(LocalModelsDir / shippage->med_image_name, NetModelsDir / shippage->med_image_name,
shippage->med_image_name, PAGETYPE_SHIP, shippointer->name);
}
if (shippage->lo_image_name[0] != 0) {
ddio_MakePath(str, LocalModelsDir, shippage->lo_image_name, NULL);
ddio_MakePath(netstr, NetModelsDir, shippage->lo_image_name, NULL);
UpdatePrimitive(str, netstr, shippage->lo_image_name, PAGETYPE_SHIP, shippointer->name);
UpdatePrimitive(LocalModelsDir / shippage->lo_image_name, NetModelsDir / shippage->lo_image_name,
shippage->lo_image_name, PAGETYPE_SHIP, shippointer->name);
}
}
#endif
@ -1029,8 +1021,7 @@ int mng_AssignShipPageToShip(mngs_ship_page *shippage, int n, CFILE *infile) {
int weapon_handle = mng_GetGuaranteedWeaponPage(shippage->weapon_name[i][j], infile);
if (weapon_handle < 0) {
mprintf(0, "Couldn't load weapon file '%s' in AssignPowPage %s...\n",
shippage->weapon_name[i][j],
mprintf(0, "Couldn't load weapon file '%s' in AssignPowPage %s...\n", shippage->weapon_name[i][j],
shippage->ship_struct.name);
shippointer->static_wb[i].gp_weapon_index[j] = LASER_INDEX;
} else
@ -1047,8 +1038,7 @@ int mng_AssignShipPageToShip(mngs_ship_page *shippage, int n, CFILE *infile) {
int fire_sound_handle = mng_GetGuaranteedSoundPage(shippage->fire_sound_name[i][j], infile);
if (fire_sound_handle < 0) {
mprintf(0, "Couldn't load fire_sound file '%s' in AssignPowPage %s...\n",
shippage->fire_sound_name[i][j],
mprintf(0, "Couldn't load fire_sound file '%s' in AssignPowPage %s...\n", shippage->fire_sound_name[i][j],
shippage->ship_struct.name);
shippointer->static_wb[i].fm_fire_sound_index[j] = SOUND_NONE_INDEX;
} else
@ -1063,8 +1053,7 @@ int mng_AssignShipPageToShip(mngs_ship_page *shippage, int n, CFILE *infile) {
int sound_handle = mng_GetGuaranteedSoundPage(shippage->firing_sound_name[i], infile);
if (sound_handle < 0) {
mprintf(0, "Couldn't load firing_sound file '%s' in AssignPowPage %s...\n",
shippage->firing_sound_name[i],
mprintf(0, "Couldn't load firing_sound file '%s' in AssignPowPage %s...\n", shippage->firing_sound_name[i],
shippage->ship_struct.name);
shippointer->firing_sound[i] = SOUND_NONE_INDEX;
} else
@ -1076,8 +1065,7 @@ int mng_AssignShipPageToShip(mngs_ship_page *shippage, int n, CFILE *infile) {
int sound_handle = mng_GetGuaranteedSoundPage(shippage->release_sound_name[i], infile);
if (sound_handle < 0) {
mprintf(0, "Couldn't load firing_sound file '%s' in AssignPowPage %s...\n",
shippage->release_sound_name[i],
mprintf(0, "Couldn't load firing_sound file '%s' in AssignPowPage %s...\n", shippage->release_sound_name[i],
shippage->ship_struct.name);
shippointer->firing_release_sound[i] = SOUND_NONE_INDEX;
} else

View File

@ -1,5 +1,5 @@
/*
* Descent 3
* Descent 3
* Copyright (C) 2024 Parallax Software
*
* This program is free software: you can redistribute it and/or modify
@ -117,6 +117,10 @@
*
* $NoKeywords: $
*/
#include <cstring>
#include <filesystem>
#include "cfile.h"
#include "manage.h"
#include "soundpage.h"
@ -125,7 +129,7 @@
#include "soundload.h"
#include "ddio.h"
#include "args.h"
#include <string.h>
// soundpage commands that are read/written
// A command is followed by a byte count describing how many bytes
// are in the data for the command
@ -321,7 +325,7 @@ int mng_FindSpecificSoundPage(char *name, mngs_sound_page *soundpage, int offset
CFILE *infile;
uint8_t pagetype;
int done = 0, found = 0;
char tablename[TABLE_NAME_LEN];
std::filesystem::path tablename;
if (Loading_locals) {
infile = cfopen(LocalTableFilename, "rb");
} else if (Loading_addon_table != -1) {
@ -330,9 +334,9 @@ int mng_FindSpecificSoundPage(char *name, mngs_sound_page *soundpage, int offset
if (Network_up && Starting_editor) {
int farg = FindArg("-filter");
if (farg)
strcpy(tablename, GameArgs[farg + 1]);
tablename = GameArgs[farg + 1];
else
ddio_MakePath(tablename, LocalTableDir, NET_TABLE, NULL);
tablename = LocalTableDir / NET_TABLE;
infile = cfopen(tablename, "rb");
} else {
infile = NULL;
@ -404,12 +408,8 @@ int mng_AssignSoundPageToSound(mngs_sound_page *soundpage, int n) {
// If its a release version, don't do any of this
#ifndef RELEASE
if (Network_up) {
char str[200];
char netstr[200];
ddio_MakePath(str, LocalSoundsDir, soundpage->raw_name, NULL);
ddio_MakePath(netstr, NetSoundsDir, soundpage->raw_name, NULL);
UpdatePrimitive(str, netstr, soundpage->raw_name, PAGETYPE_SOUND, soundpointer->name);
UpdatePrimitive(LocalSoundsDir / soundpage->raw_name, NetSoundsDir / soundpage->raw_name, soundpage->raw_name,
PAGETYPE_SOUND, soundpointer->name);
}
#endif
// Try and load our sound raw from the disk

View File

@ -1,5 +1,5 @@
/*
* Descent 3
* Descent 3
* Copyright (C) 2024 Parallax Software
*
* This program is free software: you can redistribute it and/or modify
@ -257,6 +257,9 @@
* $NoKeywords: $
*/
#include <cstring>
#include <filesystem>
#include "cfile.h"
#include "manage.h"
#include "gametexture.h"
@ -264,7 +267,6 @@
#include "mono.h"
#include "pserror.h"
#include "texpage.h"
#include <string.h>
#include "vclip.h"
#include "ddio.h"
#include "args.h"
@ -841,7 +843,7 @@ int mng_FindSpecificTexPage(char *name, mngs_texture_page *texpage, int offset)
uint8_t pagetype;
int done = 0, found = 0;
int first_try = 1;
char tablename[TABLE_NAME_LEN];
std::filesystem::path tablename;
if (Loading_locals) {
infile = cfopen(LocalTableFilename, "rb");
@ -852,9 +854,9 @@ int mng_FindSpecificTexPage(char *name, mngs_texture_page *texpage, int offset)
int farg = FindArg("-filter");
if (farg)
strcpy(tablename, GameArgs[farg + 1]);
tablename = GameArgs[farg + 1];
else
ddio_MakePath(tablename, LocalTableDir, NET_TABLE, NULL);
tablename = LocalTableDir / NET_TABLE;
infile = cfopen(tablename, "rb");
} else {
@ -944,13 +946,8 @@ int mng_AssignTexPageToTexture(mngs_texture_page *texpage, int n, CFILE *infile)
// If this is a release, don't do any of this stuff
#ifndef RELEASE
if (Network_up) {
char str[200];
char netstr[200];
ddio_MakePath(str, LocalManageGraphicsDir, texpage->bitmap_name, NULL);
ddio_MakePath(netstr, ManageGraphicsDir, texpage->bitmap_name, NULL);
UpdatePrimitive(str, netstr, texpage->bitmap_name, PAGETYPE_TEXTURE, tex->name);
UpdatePrimitive(LocalManageGraphicsDir / texpage->bitmap_name, ManageGraphicsDir / texpage->bitmap_name,
texpage->bitmap_name, PAGETYPE_TEXTURE, tex->name);
}
#endif

View File

@ -1,5 +1,5 @@
/*
* Descent 3
* Descent 3
* Copyright (C) 2024 Parallax Software
*
* This program is free software: you can redistribute it and/or modify
@ -286,6 +286,10 @@
*
* $NoKeywords: $
*/
#include <cstring>
#include <filesystem>
#include "cfile.h"
#include "manage.h"
#include "weapon.h"
@ -299,7 +303,6 @@
#include "ddio.h"
#include "gametexture.h"
#include "texpage.h"
#include <string.h>
#include "sounds.h"
#include "genericpage.h"
#include "args.h"
@ -1162,7 +1165,7 @@ int mng_FindSpecificWeaponPage(char *name, mngs_weapon_page *weaponpage) {
uint8_t pagetype;
int done = 0, found = 0;
int first_try = 1;
char tablename[TABLE_NAME_LEN];
std::filesystem::path tablename;
if (Loading_locals) {
infile = cfopen(LocalTableFilename, "rb");
@ -1173,9 +1176,9 @@ int mng_FindSpecificWeaponPage(char *name, mngs_weapon_page *weaponpage) {
int farg = FindArg("-filter");
if (farg)
strcpy(tablename, GameArgs[farg + 1]);
tablename = GameArgs[farg + 1];
else
ddio_MakePath(tablename, LocalTableDir, NET_TABLE, NULL);
tablename = LocalTableDir / NET_TABLE;
infile = cfopen(tablename, "rb");
} else {
@ -1246,13 +1249,13 @@ int mng_FindSpecificWeaponPage(char *name, mngs_weapon_page *weaponpage, int off
infile = cfopen(AddOnDataTables[Loading_addon_table].AddOnTableFilename, "rb");
} else {
if (Network_up && Starting_editor) {
char tablename[TABLE_NAME_LEN];
std::filesystem::path tablename;
int farg = FindArg("-filter");
if (farg)
strcpy(tablename, GameArgs[farg + 1]);
tablename = GameArgs[farg + 1];
else
ddio_MakePath(tablename, LocalTableDir, NET_TABLE, NULL);
tablename = LocalTableDir / NET_TABLE;
infile = cfopen(tablename, "rb");
} else {
@ -1377,24 +1380,20 @@ int mng_AssignWeaponPageToWeapon(mngs_weapon_page *weaponpage, int n, CFILE *inf
#ifndef RELEASE
if (Network_up) {
char str[200];
char netstr[200];
std::filesystem::path str = LocalManageGraphicsDir;
std::filesystem::path netstr = ManageGraphicsDir;
ddio_MakePath(str, LocalManageGraphicsDir, weaponpage->hud_image_name, NULL);
ddio_MakePath(netstr, ManageGraphicsDir, weaponpage->hud_image_name, NULL);
UpdatePrimitive(str, netstr, weaponpage->hud_image_name, PAGETYPE_WEAPON, weaponpointer->name);
UpdatePrimitive(str / weaponpage->hud_image_name, netstr / weaponpage->hud_image_name, weaponpage->hud_image_name,
PAGETYPE_WEAPON, weaponpointer->name);
// Now copy the discharge image, depending on whether or not its a model
if ((weaponpage->weapon_struct.flags & WF_IMAGE_BITMAP) || (weaponpage->weapon_struct.flags & WF_IMAGE_VCLIP)) {
ddio_MakePath(str, LocalManageGraphicsDir, weaponpage->fire_image_name, NULL);
ddio_MakePath(netstr, ManageGraphicsDir, weaponpage->fire_image_name, NULL);
} else {
ddio_MakePath(str, LocalModelsDir, weaponpage->fire_image_name, NULL);
ddio_MakePath(netstr, NetModelsDir, weaponpage->fire_image_name, NULL);
if (!((weaponpage->weapon_struct.flags & WF_IMAGE_BITMAP) || (weaponpage->weapon_struct.flags & WF_IMAGE_VCLIP))) {
str = LocalModelsDir;
netstr = NetModelsDir;
}
UpdatePrimitive(str, netstr, weaponpage->fire_image_name, PAGETYPE_WEAPON, weaponpointer->name);
UpdatePrimitive(str / weaponpage->fire_image_name, netstr / weaponpage->fire_image_name,
weaponpage->fire_image_name, PAGETYPE_WEAPON, weaponpointer->name);
}
#endif
@ -1479,7 +1478,8 @@ int mng_AssignWeaponPageToWeapon(mngs_weapon_page *weaponpage, int n, CFILE *inf
img_handle = mng_GetGuaranteedWeaponPage(weaponpage->alternate_spawn_name, infile);
if (img_handle < 0) {
mprintf(0, "Couldn't load alternate spawn weapon '%s' in AssignWeaponPage...\n", weaponpage->alternate_spawn_name);
mprintf(0, "Couldn't load alternate spawn weapon '%s' in AssignWeaponPage...\n",
weaponpage->alternate_spawn_name);
weaponpointer->alternate_spawn_handle = -1;
} else
weaponpointer->alternate_spawn_handle = img_handle;
@ -1548,8 +1548,7 @@ int mng_AssignWeaponPageToWeapon(mngs_weapon_page *weaponpage, int n, CFILE *inf
sound_handle = mng_GetGuaranteedSoundPage(weaponpage->sound_name[i]);
if (sound_handle < 0) {
mprintf(0, "Couldn't load sound file '%s' in AssignWeaponPage. Weapon=%s\n",
weaponpage->sound_name[i],
mprintf(0, "Couldn't load sound file '%s' in AssignWeaponPage. Weapon=%s\n", weaponpage->sound_name[i],
weaponpage->weapon_struct.name);
weaponpointer->sounds[i] = SOUND_NONE_INDEX;
} else

View File

@ -274,30 +274,28 @@ void mve_SetRenderProperties(int16_t x, int16_t y, int16_t w, int16_t h, rendere
#ifdef __LINUX__
// locates the case-sensitive movie file name
bool mve_FindMovieFileRealName(const char *movie, char *real_name) {
std::filesystem::path mve_FindMovieFileRealName(const std::filesystem::path &movie) {
// split into directory and file...
char t_dir[_MAX_PATH];
char t_file[_MAX_PATH];
char t_ext[256];
char t_out[_MAX_PATH];
ddio_SplitPath(movie, t_dir, t_file, t_ext);
// pop the extension back on..
strcat(t_file, t_ext);
std::filesystem::path t_file = movie.filename();
std::filesystem::path t_dir = movie.parent_path();
std::filesystem::path t_out;
// found a directory?
if (strlen(t_dir) > 0) {
if (!t_dir.empty()) {
// map the bits (or fail)
if (!cf_FindRealFileNameCaseInsenstive(t_dir, t_file, t_out))
return false;
t_out = cf_FindRealFileNameCaseInsensitive(t_file, t_dir);
if (t_out.empty())
return t_out;
// re-assemble
ddio_MakePath(real_name, t_dir, t_out, NULL);
return (t_dir / t_out);
} else {
// just a file, map that
if (!cf_FindRealFileNameCaseInsenstive(NULL, t_file, t_out))
return false;
t_out = cf_FindRealFileNameCaseInsensitive(t_file);
if (t_out.empty())
return t_out;
// re-assemble
strcpy(real_name, t_out);
return t_out;
}
return true;
}
#endif
@ -305,19 +303,20 @@ bool mve_FindMovieFileRealName(const char *movie, char *real_name) {
int mve_PlayMovie(const char *pMovieName, oeApplication *pApp) {
#ifndef NO_MOVIES
// first, find that movie..
char real_name[_MAX_PATH];
std::filesystem::path real_name;
#ifdef __LINUX__
if (!mve_FindMovieFileRealName(pMovieName, real_name)) {
real_name = mve_FindMovieFileRealName(pMovieName);
if (real_name.empty()) {
mprintf(0, "MOVIE: No such file %s\n", pMovieName);
return MVELIB_FILE_ERROR;
}
#else
strcpy(real_name, pMovieName);
real_name = pMovieName;
#endif
// open movie file.
int hFile = open(real_name, O_RDONLY | O_BINARY);
int hFile = open(real_name.u8string().c_str(), O_RDONLY | O_BINARY);
if (hFile == -1) {
mprintf(0, "MOVIE: Unable to open %s\n", real_name);
mprintf(0, "MOVIE: Unable to open %s\n", real_name.u8string().c_str());
return MVELIB_FILE_ERROR;
}
@ -527,22 +526,22 @@ void CallbackShowFrame(uint8_t *buf, uint32_t bufw, uint32_t bufh, uint32_t sx,
intptr_t mve_SequenceStart(const char *mvename, int *fhandle, oeApplication *app, bool looping) {
#ifndef NO_MOVIES
// first, find that movie..
char real_name[_MAX_PATH];
std::filesystem::path real_name;
#ifdef __LINUX__
if (!mve_FindMovieFileRealName(mvename, real_name)) {
real_name = mve_FindMovieFileRealName(mvename);
if (real_name.empty()) {
mprintf(0, "MOVIE: No such file %s\n", mvename);
*fhandle = -1;
return 0;
}
#else
strcpy(real_name, mvename);
real_name = mvename;
#endif
int hfile = open(real_name, O_RDONLY | O_BINARY);
int hfile = open(real_name.u8string().c_str(), O_RDONLY | O_BINARY);
if (hfile == -1) {
mprintf(1, "MOVIE: Unable to open %s\n", real_name);
mprintf(1, "MOVIE: Unable to open %s\n", real_name.u8string().c_str());
*fhandle = -1;
return 0;
}