Fixed and refactored code in FileSystem.cpp (from Mr.Stalin)

This commit is contained in:
NovaRain
2019-01-20 00:20:51 +08:00
parent 12ad41043d
commit 7b5075042d
3 changed files with 97 additions and 87 deletions
+1 -1
View File
@@ -60,7 +60,7 @@ get/set_unspent_ap_bonus alter the AC bonus you receive per unused action point
nb_* functions are reserved for the brotherhood tactical training mod, and should be avoided.
The fs_* functions are used to manipulate a virtual file system. Files saved here should have paths relative to the data folder, and use backslashes as the directory separator. They will take precedence over files stored in the normal data folder. They will also be saved into save games, so be avoid creating large files. Using fs_copy followed by fs_read_xxx, you can read the contents of existing files.
The fs_* functions are used to manipulate a virtual file system. Files saved here should have paths relative to the data folder, and use backslashes as the directory separator. They will take precedence over files stored in the normal data folder. They will also be saved into save games if you set a flag for them using fs_resize(fileId, -1), so be avoid creating large files. Using fs_copy followed by fs_read_xxx, you can read the contents of existing files.
get/set_proto_data are used to manipulate the in memory copies of the .pro files Fallout makes when they are loaded. The offset refers to the offset in memory from the start of the proto to the element you are reading. Changes are not stored on disc, and are not permanent. If you modify the protos, and then Fallout subsequently reloads the file your changes will be lost.
+1 -1
View File
@@ -219,7 +219,7 @@
0x81e9 - int get_unspent_ap_perk_bonus()
0x81ec - float sqrt(float)
0x81ed - float abs(float)
0x81ed - int/float abs(int/float)
0x81ee - float sin(float)
0x81ef - float cos(float)
0x81f0 - float tan(float)
+95 -85
View File
@@ -22,23 +22,24 @@
#include "FalloutEngine.h"
#include "FileSystem.h"
#if (_MSC_VER < 1600)
#include "Cpp11_emu.h"
#endif
extern void GetSavePath(char* buf, char* ftype);
#define MAX_FILE_SIZE 0xA00000
struct fsFile {
char* data;
BYTE* data;
DWORD length;
char name[128];
DWORD wpos;
DWORD wpos; // current fs read/write position
BYTE isSave;
};
std::vector<fsFile> files;
static DWORD loadedFiles = 0;
bool UsingFileSystem = false;
struct openFile {
DWORD pos;
DWORD pos; // current xread/xwrite position
fsFile* file;
openFile(fsFile* pFile) {
@@ -49,9 +50,14 @@ struct openFile {
struct sFile {
DWORD type;
openFile* file;
openFile* opnFile;
};
std::vector<fsFile> files;
static DWORD loadedFiles = 0; // used for internal sfall data
bool UsingFileSystem = false;
static const DWORD xfcloseAddr[] = {
0x4C5DBD, 0x4C5EA5, 0x4C5EB4,
};
@@ -81,7 +87,7 @@ static const DWORD xfilelengthAddr[] = {
};
static void _stdcall xfclose(sFile* file) {
delete file->file;
delete file->opnFile;
delete file;
}
@@ -104,7 +110,7 @@ static sFile* _stdcall xfopen(const char* path, const char* mode) {
if (!_stricmp(path, files[i].name)) {
sFile* file = new sFile();
file->type = 3;
file->file = new openFile(&files[i]);
file->opnFile = new openFile(&files[i]);
return file;
}
}
@@ -147,9 +153,9 @@ end:
}
}
static int _stdcall xfgetc(sFile* file) {
if (file->file->pos >= file->file->file->length) return -1;
return file->file->file->data[file->file->pos++];
static DWORD _stdcall xfgetc(sFile* file) {
if (file->opnFile->pos >= file->opnFile->file->length) return -1;
return static_cast<DWORD>(file->opnFile->file->data[file->opnFile->pos++]);
}
static __declspec(naked) int asm_xfgetc(sFile* file) {
@@ -169,7 +175,7 @@ end:
}
static char* _stdcall xfgets(char* buf, int max_count, sFile* file) {
if (file->file->pos >= file->file->file->length) return 0;
if (file->opnFile->pos >= file->opnFile->file->length) return 0;
for (int i = 0; i < max_count; i++) {
int c = xfgetc(file);
if (c == -1) {
@@ -238,9 +244,9 @@ end:
}
static int _stdcall xfungetc(int c, sFile* file) {
if (file->file->pos == 0) return -1;
if (file->file->file->data[file->file->pos - 1] != c) return -1;
file->file->pos--;
if (file->opnFile->pos == 0) return -1;
if (file->opnFile->file->data[file->opnFile->pos - 1] != static_cast<BYTE>(c)) return -1;
file->opnFile->pos--;
return c;
}
@@ -261,9 +267,10 @@ end:
static int __fastcall xfread(sFile* file, int elsize, void* buf, int count) {
for (int i = 0; i < count; i++) {
if (file->file->pos + elsize >= file->file->file->length) return i;
memcpy(buf, &file->file->file->data[file->file->pos], elsize);
file->file->pos += elsize;
if (file->opnFile->pos + elsize > file->opnFile->file->length) return i;
memcpy(buf, &file->opnFile->file->data[file->opnFile->pos], elsize);
file->opnFile->pos += elsize;
}
return count;
}
@@ -301,13 +308,13 @@ end:
static int _stdcall xfseek(sFile* file, long pos, int origin) {
switch(origin) {
case 0:
file->file->pos = pos;
file->opnFile->pos = pos;
break;
case 1:
file->file->pos += pos;
file->opnFile->pos += pos;
break;
case 2:
file->file->pos = file->file->file->length + pos;
file->opnFile->pos = file->opnFile->file->length + pos;
break;
}
return 0;
@@ -330,7 +337,7 @@ end:
}
static long _stdcall xftell(sFile* file) {
return file->file->pos;
return file->opnFile->pos;
}
static __declspec(naked) long asm_xftell(sFile* file) {
@@ -350,8 +357,9 @@ end:
}
static void _stdcall xfrewind(sFile* file) {
file->file->pos = 0;
file->opnFile->pos = 0;
}
static __declspec(naked) void asm_xfrewind(sFile* file) {
__asm {
cmp [eax], 3;
@@ -367,7 +375,7 @@ end:
}
static int _stdcall xfeof(sFile* file) {
if (file->file->pos >= file->file->file->length) {
if (file->opnFile->pos >= file->opnFile->file->length) {
return 1;
}
return 0;
@@ -390,7 +398,7 @@ end:
}
static int _stdcall xfilelength(sFile* file) {
return file->file->file->length;
return file->opnFile->file->length;
}
static __declspec(naked) int asm_xfilelength(sFile* file) {
@@ -410,25 +418,25 @@ end:
}
void FileSystemReset() {
//if (!UsingFileSystem) return;
if (files.empty()) return;
for (DWORD i = loadedFiles; i < files.size(); i++) {
if (files[i].data) delete[] files[i].data;
}
if (!loadedFiles) {
files.clear();
} else {
for (DWORD i = files.size() - 1; i >= loadedFiles; i--) files.erase(files.begin() + i);
files.erase(files.begin() + loadedFiles, files.end() - 1);
}
}
void FileSystemSave(HANDLE h) {
DWORD count = 0, unused;
for (DWORD i = 0; i < files.size(); i++) {
if (files[i].data) count++;
for (DWORD i = loadedFiles; i < files.size(); i++) {
if (files[i].isSave && files[i].data) count++;
}
WriteFile(h, &count, 4, &unused, 0);
for (DWORD i = 0; i < files.size(); i++) {
if (files[i].data) {
for (DWORD i = loadedFiles; i < files.size(); i++) {
if (files[i].isSave && files[i].data) {
WriteFile(h, &files[i].length, 128 + 8, &unused, 0);
WriteFile(h, files[i].data, files[i].length, &unused, 0);
}
@@ -448,8 +456,9 @@ static void FileSystemLoad() {
for (DWORD i = 0; i < count; i++) {
fsFile file;
ReadFile(h, &file.length, 128 + 8, &read, 0);
file.data = new char[file.length];
file.data = new BYTE[file.length];
ReadFile(h, file.data, file.length, &read, 0);
file.isSave = 1;
files.push_back(file);
}
}
@@ -513,21 +522,11 @@ void FileSystemInit() {
}
}
DWORD _stdcall FScreate(const char* path, int size) {
for (DWORD i = 0; i < files.size(); i++) {
if (!files[i].data) {
files[i].data = new char[size];
strcpy_s(files[i].name, path);
files[i].length = size;
files[i].wpos = 0;
return i;
}
}
fsFile file;
file.data = new char[size];
DWORD NewFile(fsFile &file, const char* path, int size) {
strcpy_s(file.name, path);
file.length = size;
file.wpos = 0;
file.isSave = 0;
files.push_back(file);
return files.size() - 1;
}
@@ -535,13 +534,27 @@ DWORD _stdcall FScreate(const char* path, int size) {
DWORD _stdcall FScreateFromData(const char* path, void* data, int size) {
loadedFiles++;
fsFile file;
file.data = new char[size];
file.data = new BYTE[size];
memcpy(file.data, data, size);
strcpy_s(file.name, path);
file.length = size;
file.wpos = 0;
files.push_back(file);
return files.size() - 1;
return NewFile(file, path, size); // return file index in vector
}
DWORD _stdcall FScreate(const char* path, int size) {
if (size > MAX_FILE_SIZE) return -1; // size limit 10Mb
for (DWORD i = 0; i < files.size(); i++) {
if (!files[i].data) {
files[i].data = new BYTE[size];
strcpy_s(files[i].name, path);
files[i].length = size;
files[i].wpos = 0;
return i;
}
}
fsFile file;
file.data = new BYTE[size];
return NewFile(file, path, size); // return file index in vector
}
DWORD _stdcall FScopy(const char* path, const char* source) {
@@ -566,7 +579,7 @@ DWORD _stdcall FScopy(const char* path, const char* source) {
mov fsize, eax;
}
char* fdata = new char[fsize];
BYTE* fdata = new BYTE[fsize];
__asm {
mov eax, file;
call xfclose_;
@@ -575,7 +588,7 @@ DWORD _stdcall FScopy(const char* path, const char* source) {
call db_read_to_buf_;
}
fsFile* fsfile = 0;
fsFile* fsfile = nullptr;
for (DWORD i = 0; i < files.size(); i++) {
if (!files[i].data) {
result = i;
@@ -586,14 +599,15 @@ DWORD _stdcall FScopy(const char* path, const char* source) {
if (!fsfile) {
files.push_back(fsFile());
result = files.size() - 1;
fsfile = &files[result];
fsfile = &files.back();
}
fsfile->data = fdata;
strcpy_s(fsfile->name, path);
fsfile->length = fsize;
fsfile->wpos = 0;
fsfile->isSave = 0;
return result;
return result; // return file index in vector
}
DWORD _stdcall FSfind(const char* path) {
@@ -613,26 +627,21 @@ void _stdcall FSwrite_byte(DWORD id, int data) {
void _stdcall FSwrite_short(DWORD id, int data) {
if (id >= files.size() || !files[id].data) return;
if (files[id].wpos + 2 > files[id].length) return;
char data2[2];
memcpy(data2, &data, 2);
char c = data2[0];
data2[0] = data2[1];
data2[1] = c;
for (int i = 0; i < 2; i++) files[id].data[files[id].wpos++] = data2[i];
char* data2 = (char*)&data;
data2++;
// write & reverse bytes
for (int i = 0; i < 2; i++) files[id].data[files[id].wpos++] = *(data2 - i);
}
void _stdcall FSwrite_int(DWORD id, int data) {
if (id >= files.size() || !files[id].data) return;
if (files[id].wpos + 4 > files[id].length) return;
char data2[4];
memcpy(data2, &data, 4);
char c = data2[1];
data2[1] = data2[2];
data2[2] = c;
c = data2[0];
data2[0] = data2[3];
data2[3] = c;
for (int i = 0; i < 4; i++) files[id].data[files[id].wpos++] = data2[i];
char* data2 = (char*)&data;
data2 += 3;
// write & reverse bytes
for (int i = 0; i < 4; i++) files[id].data[files[id].wpos++] = *(data2 - i);
}
void _stdcall FSwrite_string(DWORD id, const char* data) {
@@ -658,25 +667,22 @@ int _stdcall FSread_byte(DWORD id) {
int _stdcall FSread_short(DWORD id) {
if (id >= files.size() || !files[id].data) return 0;
if (files[id].wpos + 2 > files[id].length) return 0;
char data[2];
data[1] = files[id].data[files[id].wpos++];
data[0] = files[id].data[files[id].wpos++];
short result;
memcpy(&result, data, 2);
return result;
return static_cast<int>(*(short*)data);
}
int _stdcall FSread_int(DWORD id) {
if (id >= files.size() || !files[id].data) return 0;
if (files[id].wpos + 4 > files[id].length) return 0;
char data[4];
data[3] = files[id].data[files[id].wpos++];
data[2] = files[id].data[files[id].wpos++];
data[1] = files[id].data[files[id].wpos++];
data[0] = files[id].data[files[id].wpos++];
int result;
memcpy(&result, data, 4);
return result;
for (int i = 3; i >= 0; i--) data[i] = files[id].data[files[id].wpos++];
return *(int*)data;
}
void _stdcall FSdelete(DWORD id) {
@@ -705,9 +711,13 @@ void _stdcall FSseek(DWORD id, DWORD pos) {
}
void _stdcall FSresize(DWORD id, DWORD size) {
if (id >= files.size() || !files[id].data) return;
char* buf = files[id].data;
files[id].data = new char[size];
if (id >= files.size() || !files[id].data || (size != -1 && size > MAX_FILE_SIZE)) return; // size limit 10Mb
if (size == -1) {
files[id].isSave = 1;
return;
}
BYTE* buf = files[id].data;
files[id].data = new BYTE[size];
CopyMemory(files[id].data, buf, min(files[id].length, size));
files[id].length = size;
files[id].wpos = 0;