Files
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
2026-06-24 21:28:16 -05:00

554 lines
13 KiB
C++

#include "StuffHeaders.hpp"
#include <mbstring.h>
#define __mbschr(s,c) (char*)_mbschr((const unsigned char*)(s),(c))
#if !defined(TOOLOS_HPP)
#include <GameOS\ToolOS.hpp>
#endif
//#############################################################################
//############################# Directory ###############################
//#############################################################################
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Directory::Directory(
const char *find_files,
bool directories
):
fileEntries(NULL,NULL),
folderEntries(NULL,NULL)
{
Check_Pointer(find_files);
//
//------------------------------------------------
// Isolate the search path that we are looking for
//------------------------------------------------
//
MString new_directory_string = find_files;
currentDirectoryString = find_files;
currentDirectoryString.IsolateDirectory();
//
//---------------------------------------------------------
// Now look for the files and add each entry into the chain
//---------------------------------------------------------
//
const char* file_name = gos_FindFiles(new_directory_string);
while (file_name)
{
MString file_name_string = file_name;
DirectoryEntry *entry = new(g_Heap) DirectoryEntry(file_name_string);
Check_Object(entry);
fileEntries.AddValue(entry,file_name_string);
file_name = gos_FindFilesNext();
}
gos_FindFilesClose();
fileWalker = new(g_Heap) SortedChainIteratorOf<DirectoryEntry*,MString>(&fileEntries);
Check_Object(fileWalker);
//
//---------------------------------------------------
// Look through the directories if we are supposed to
//---------------------------------------------------
//
folderWalker = NULL;
if (directories)
{
file_name = gos_FindDirectories(new_directory_string);
while (file_name)
{
MString file_name_string = file_name;
DirectoryFolder *entry = new(g_Heap) DirectoryFolder(file_name_string);
Check_Object(entry);
folderEntries.AddValue(entry,file_name_string);
file_name = gos_FindDirectoriesNext();
}
gos_FindDirectoriesClose();
folderWalker = new(g_Heap) SortedChainIteratorOf<DirectoryFolder*,MString>(&folderEntries);
Check_Object(folderWalker);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Directory::~Directory(void)
{
Check_Object(this);
Check_Object(fileWalker);
fileWalker->DeletePlugs();
Check_Object(fileWalker);
delete fileWalker;
if (folderWalker != NULL)
{
Check_Object(folderWalker);
folderWalker->DeletePlugs();
Check_Object(folderWalker);
delete folderWalker;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
const char* Directory::GetCurrentFileName(void)
{
Check_Object(this);
Check_Object(fileWalker);
DirectoryEntry *entry;
if ((entry = fileWalker->GetCurrent()) != NULL)
{
Check_Object(entry);
return entry->GetItem();
}
return NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void Directory::AdvanceCurrentFile(void)
{
Check_Object(this);
Check_Object(fileWalker);
fileWalker->Next();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
const char * Directory::GetCurrentFolderName( void )
{
Check_Object(this);
if (folderWalker == NULL)
STOP(("Directory class was instantiated without directory support:\n Set the <directories> parameter to true to enable."));
Check_Object(folderWalker);
DirectoryFolder *entry;
if ((entry = folderWalker->GetCurrent()) != NULL)
{
Check_Object(entry);
return entry->GetItem();
}
return NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void Directory::AdvanceCurrentFolder( void )
{
Check_Object(this);
if (folderWalker == NULL)
STOP(("Directory class was instantiated without directory support:\n Set the <directories> parameter to true to enable."));
Check_Object(folderWalker);
folderWalker->Next();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
const char* Directory::GetNewestFile(void)
{
Check_Object(this);
Check_Object(fileWalker);
SortedChainIteratorOf<DirectoryEntry*, MString> file_walker(&fileEntries);
DirectoryEntry *entry;
DirectoryEntry *newest_entry;
__int64 new_file_time;
newest_entry = file_walker.GetCurrent();
if(newest_entry)
{
MString file_name = currentDirectoryString;
file_name += newest_entry->GetItem();
new_file_time = gos_FileTimeStamp((const char *)file_name);
while((entry = file_walker.ReadAndNext()) != NULL)
{
Check_Object(entry);
file_name = currentDirectoryString;
file_name += entry->GetItem();
__int64 current_file_time = gos_FileTimeStamp((const char *)file_name);
if(current_file_time > new_file_time)
{
newest_entry = entry;
new_file_time = current_file_time;
}
}
return newest_entry->GetItem();
}
return NULL;
}
//#############################################################################
//########################### FileStream ################################
//#############################################################################
FileStream::ClassData* FileStream::DefaultData = NULL;
HGOSHEAP FileStream::s_Heap = NULL;
const char * FileStream::WhiteSpace = " \t\n";
char FileStream::RedirectedName[256];
bool
FileStream::IsRedirected=false,
FileStream::IgnoreReadOnlyFlag=false;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void FileStream::InitializeClass()
{
Verify(!s_Heap);
s_Heap = gos_CreateMemoryHeap("File Buffers", 0, Stuff::g_LibraryHeap);
Check_Pointer(s_Heap);
Verify(!DefaultData);
DefaultData =
new ClassData(
FileStreamClassID,
"Stuff::FileStream",
MemoryStream::DefaultData
);
Check_Object(DefaultData);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void FileStream::TerminateClass()
{
Check_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
Check_Pointer(s_Heap);
gos_DestroyMemoryHeap(s_Heap);
s_Heap = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void FileStream::TestInstance() const
{
Verify(IsDerivedFrom(DefaultData));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
FileStream::FileStream():
MemoryStream(DefaultData, NULL, 0)
{
fileName = NULL;
isOpen = false;
fileHandle = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
FileStream::FileStream(
const char* file_name,
WriteStatus writable
):
MemoryStream(DefaultData, NULL, 0)
{
fileName = NULL;
isOpen = false;
Open(file_name, writable);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
FileStream::~FileStream()
{
Close();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void FileStream::Open(
const char* file_name,
WriteStatus writable
)
{
Check_Object(this);
Check_Pointer(file_name);
writeEnabled = writable;
currentPosition = streamStart = highWaterByte = NULL;
streamSize = 0;
fileHandle = NULL;
//
//------------------------------------------------
// If this is a readonly file, have gos read it in
//------------------------------------------------
//
if (writeEnabled == ReadOnly)
{
if (IsRedirected)
{
void (__stdcall *old_hook)(const char*, BYTE**, DWORD*) = Environment.HookGetFile;
Environment.HookGetFile = NULL;
gos_PushCurrentHeap(s_Heap);
gos_GetFile(RedirectedName, &streamStart, &streamSize);
gos_PopCurrentHeap();
Environment.HookGetFile = old_hook;
fileName = _strdup(RedirectedName);
}
else
{
gos_PushCurrentHeap(s_Heap);
gos_GetFile(file_name, &streamStart, &streamSize);
gos_PopCurrentHeap();
if (IsRedirected)
fileName = _strdup(RedirectedName);
else
fileName = _strdup(file_name);
}
isOpen = true;
currentPosition = streamStart;
highWaterByte = currentPosition;
}
//
//-----------------------------------------------
// Write only flags go through standard file open
//-----------------------------------------------
//
else
{
writeEnabled = writable;
if (IgnoreReadOnlyFlag)
{
bool (__stdcall *old_hook)(const char*) = Environment.HookDoesFileExist;
Environment.HookDoesFileExist = NULL;
if (gos_DoesFileExist(file_name))
gos_FileSetReadWrite(file_name);
Environment.HookDoesFileExist = old_hook;
}
gos_OpenFile(
&fileHandle,
file_name,
READWRITE
);
isOpen = true;
streamSize = 0xFFFFFFFFU;
fileName = _strdup(file_name);
}
//
//--------------------------
// Try and open the filename
//--------------------------
//
IsRedirected = false;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void FileStream::Close()
{
Check_Object(this);
//
//---------------------------------
// If the file was opened, close it
//---------------------------------
//
if (fileHandle)
{
gos_CloseFile(fileHandle);
fileHandle = NULL;
}
else if (streamStart != NULL)
gos_Free(streamStart);
//
//----------------
// Delete the name
//----------------
//
isOpen = false;
if (fileName)
{
Check_Pointer(fileName);
free(fileName);
fileName = NULL;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void FileStream::SetPointer(DWORD index)
{
Check_Object(this);
Verify(IsFileOpened());
MemoryStream::SetPointer(index);
if (writeEnabled == WriteOnly)
gos_SeekFile(fileHandle, FROMSTART, reinterpret_cast<DWORD>(currentPosition));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MemoryStream& FileStream::AdvancePointer(DWORD index)
{
Check_Object(this);
Verify(IsFileOpened());
MemoryStream::AdvancePointer(index);
if (writeEnabled == WriteOnly)
gos_SeekFile(fileHandle, FROMSTART, reinterpret_cast<DWORD>(currentPosition));
return *this;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MemoryStream& FileStream::RewindPointer(DWORD index)
{
Check_Object(this);
Verify(IsFileOpened());
MemoryStream::RewindPointer(index);
if (writeEnabled == WriteOnly)
gos_SeekFile(fileHandle, FROMSTART, reinterpret_cast<DWORD>(currentPosition));
return *this;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MemoryStream& FileStream::ReadBytes(
void *ptr,
DWORD number_of_bytes
)
{
Check_Object(this);
Verify(IsFileOpened());
Verify(writeEnabled == ReadOnly);
return MemoryStream::ReadBytes(ptr, number_of_bytes);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MemoryStream& FileStream::WriteBytes(
const void *ptr,
DWORD number_of_bytes
)
{
Check_Object(this);
Verify(IsFileOpened());
Verify(writeEnabled == WriteOnly);
DWORD written =
gos_WriteFile(
fileHandle,
Cast_Pointer(BYTE*, const_cast<void*>(ptr)),
number_of_bytes
);
Verify(written == number_of_bytes);
currentPosition += written;
return *this;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool FileStream::IsFileOpened()
{
Check_Object(this);
return isOpen;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool Stuff::CreateDirectories(const char *directory_path)
{
if (directory_path == NULL)
return false;
Check_Pointer(directory_path);
const char *start_position = directory_path;
const char *current_position = directory_path;
if (*current_position != '\\')
{
if ((current_position + 1) != NULL)
{
if((current_position + 2) != NULL)
{
if ( *(current_position + 1) == ':' && *(current_position + 2) == '\\')
{
current_position += 2;
}
}
}
}
if (*current_position != '\\')
return false;
while((current_position != NULL))
{
//make a substring with the path...
const char *next_slash;
next_slash = __mbschr( current_position + 1, '\\' );
char *new_string = NULL;
if (next_slash == NULL)
{
//copy the whole string
int length = strlen(start_position)+1;
new_string = new(g_Heap) char[length];
Check_Pointer(new_string);
Str_Copy(new_string, start_position, length);
}
else
{
if (next_slash - current_position == 0)
{
return false;
}
if (next_slash - current_position == 1)
{
return false;
}
//copy the sub string
int length = next_slash - start_position;
new_string = new(g_Heap) char[length+1];
Check_Pointer(new_string);
strncpy(new_string, start_position, length);
new_string[length] = NULL;
}
Verify(new_string != NULL);
if (!gos_DoesFileExist(new_string))
{
gos_CreateDirectory(new_string);
}
Check_Pointer(new_string);
delete new_string;
current_position = next_slash;
}
return true;
}