| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- /*
- ** Command & Conquer Generals(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** 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/>.
- */
- ////////////////////////////////////////////////////////////////////////////////
- // //
- // (c) 2001-2003 Electronic Arts Inc. //
- // //
- ////////////////////////////////////////////////////////////////////////////////
- //////// Win32BIGFileSystem.h ///////////////////////////
- // Bryan Cleveland, August 2002
- /////////////////////////////////////////////////////////////
- #include <winsock2.h>
- #include "Common/AudioAffect.h"
- #include "Common/ArchiveFile.h"
- #include "Common/ArchiveFileSystem.h"
- #include "Common/File.h"
- #include "Common/GameAudio.h"
- #include "Common/GameMemory.h"
- #include "Common/LocalFileSystem.h"
- #include "Win32Device/Common/Win32BIGFile.h"
- #include "Win32Device/Common/Win32BIGFileSystem.h"
- #ifdef _INTERNAL
- // for occasional debugging...
- //#pragma optimize("", off)
- //#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
- #endif
- static const char *BIGFileIdentifier = "BIGF";
- Win32BIGFileSystem::Win32BIGFileSystem() : ArchiveFileSystem() {
- }
- Win32BIGFileSystem::~Win32BIGFileSystem() {
- }
- void Win32BIGFileSystem::init() {
- DEBUG_ASSERTCRASH(TheLocalFileSystem != NULL, ("TheLocalFileSystem must be initialized before TheArchiveFileSystem."));
- if (TheLocalFileSystem == NULL) {
- return;
- }
- loadBigFilesFromDirectory("", "*.big");
- }
- void Win32BIGFileSystem::reset() {
- }
- void Win32BIGFileSystem::update() {
- }
- void Win32BIGFileSystem::postProcessLoad() {
- }
- ArchiveFile * Win32BIGFileSystem::openArchiveFile(const Char *filename) {
- File *fp = TheLocalFileSystem->openFile(filename, File::READ | File::BINARY);
- AsciiString archiveFileName;
- archiveFileName = filename;
- archiveFileName.toLower();
- Int archiveFileSize = 0;
- Int numLittleFiles = 0;
- ArchiveFile *archiveFile = NEW Win32BIGFile;
- DEBUG_LOG(("Win32BIGFileSystem::openArchiveFile - opening BIG file %s\n", filename));
- if (fp == NULL) {
- DEBUG_CRASH(("Could not open archive file %s for parsing", filename));
- return NULL;
- }
- AsciiString asciibuf;
- char buffer[_MAX_PATH];
- fp->read(buffer, 4); // read the "BIG" at the beginning of the file.
- buffer[4] = 0;
- if (strcmp(buffer, BIGFileIdentifier) != 0) {
- DEBUG_CRASH(("Error reading BIG file identifier in file %s", filename));
- fp->close();
- fp = NULL;
- return NULL;
- }
- // read in the file size.
- fp->read(&archiveFileSize, 4);
- DEBUG_LOG(("Win32BIGFileSystem::openArchiveFile - size of archive file is %d bytes\n", archiveFileSize));
- // char t;
- // read in the number of files contained in this BIG file.
- // change the order of the bytes cause the file size is in reverse byte order for some reason.
- fp->read(&numLittleFiles, 4);
- numLittleFiles = ntohl(numLittleFiles);
- DEBUG_LOG(("Win32BIGFileSystem::openArchiveFile - %d are contained in archive\n", numLittleFiles));
- // for (Int i = 0; i < 2; ++i) {
- // t = buffer[i];
- // buffer[i] = buffer[(4-i)-1];
- // buffer[(4-i)-1] = t;
- // }
- // seek to the beginning of the directory listing.
- fp->seek(0x10, File::START);
- // read in each directory listing.
- ArchivedFileInfo *fileInfo = NEW ArchivedFileInfo;
- for (Int i = 0; i < numLittleFiles; ++i) {
- Int filesize = 0;
- Int fileOffset = 0;
- fp->read(&fileOffset, 4);
- fp->read(&filesize, 4);
- filesize = ntohl(filesize);
- fileOffset = ntohl(fileOffset);
- fileInfo->m_archiveFilename = archiveFileName;
- fileInfo->m_offset = fileOffset;
- fileInfo->m_size = filesize;
-
- // read in the path name of the file.
- Int pathIndex = -1;
- do {
- ++pathIndex;
- fp->read(buffer + pathIndex, 1);
- } while (buffer[pathIndex] != 0);
- Int filenameIndex = pathIndex;
- while ((buffer[filenameIndex] != '\\') && (buffer[filenameIndex] != '/') && (filenameIndex >= 0)) {
- --filenameIndex;
- }
- fileInfo->m_filename = (char *)(buffer + filenameIndex + 1);
- fileInfo->m_filename.toLower();
- buffer[filenameIndex + 1] = 0;
- AsciiString path;
- path = buffer;
- AsciiString debugpath;
- debugpath = path;
- debugpath.concat(fileInfo->m_filename);
- // DEBUG_LOG(("Win32BIGFileSystem::openArchiveFile - adding file %s to archive file %s, file number %d\n", debugpath.str(), fileInfo->m_archiveFilename.str(), i));
- archiveFile->addFile(path, fileInfo);
- }
- archiveFile->attachFile(fp);
- delete fileInfo;
- fileInfo = NULL;
- // leave fp open as the archive file will be using it.
- return archiveFile;
- }
- void Win32BIGFileSystem::closeArchiveFile(const Char *filename) {
- // Need to close the specified big file
- ArchiveFileMap::iterator it = m_archiveFileMap.find(filename);
- if (it == m_archiveFileMap.end()) {
- return;
- }
- if (stricmp(filename, MUSIC_BIG) == 0) {
- // Stop the current audio
- TheAudio->stopAudio(AudioAffect_Music);
- // No need to turn off other audio, as the lookups will just fail.
- }
- DEBUG_ASSERTCRASH(stricmp(filename, MUSIC_BIG) == 0, ("Attempting to close Archive file '%s', need to add code to handle its shutdown correctly.", filename));
- // may need to do some other processing here first.
-
- delete (it->second);
- m_archiveFileMap.erase(it);
- }
- void Win32BIGFileSystem::closeAllArchiveFiles() {
- }
- void Win32BIGFileSystem::closeAllFiles() {
- }
- Bool Win32BIGFileSystem::loadBigFilesFromDirectory(AsciiString dir, AsciiString fileMask, Bool overwrite) {
- FilenameList filenameList;
- TheLocalFileSystem->getFileListInDirectory(dir, AsciiString(""), fileMask, filenameList, TRUE);
- Bool actuallyAdded = FALSE;
- FilenameListIter it = filenameList.begin();
- while (it != filenameList.end()) {
- ArchiveFile *archiveFile = openArchiveFile((*it).str());
- if (archiveFile != NULL) {
- DEBUG_LOG(("Win32BIGFileSystem::loadBigFilesFromDirectory - loading %s into the directory tree.\n", (*it).str()));
- loadIntoDirectoryTree(archiveFile, *it, overwrite);
- m_archiveFileMap[(*it)] = archiveFile;
- DEBUG_LOG(("Win32BIGFileSystem::loadBigFilesFromDirectory - %s inserted into the archive file map.\n", (*it).str()));
- actuallyAdded = TRUE;
- }
- it++;
- }
- return actuallyAdded;
- }
|