forked from scp-fs2open/PCS2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathVPReader.cpp
202 lines (166 loc) · 5.38 KB
/
VPReader.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
// VPReader.cpp
// Derek Meek
// For Reading Volition Packfiles associated with freespace 2
/*
* $Logfile: /VPReader.cpp $
* $Revision: 1.12 $
* $Date: 2008/02/09 23:01:41 $
* $Author: kazan $
*
* $Log: VPReader.cpp,v $
* Revision 1.12 2008/02/09 23:01:41 kazan
* post-kaz_templates removal cleanup
*
* Revision 1.11 2008/02/09 22:28:09 kazan
* checkin before i do something drastic (pull out my templates - don't need them anymore)
*
* Revision 1.10 2008/02/04 18:02:44 kazan
* Dumbest typo that latest forever found while fixing the dumbest bug ever - VolitionPackfileReader::FindFileWild was case sensative.. causing PCS2 not to load textures in VPs when there was a case mismatch
*
* Revision 1.9 2007/07/13 11:31:04 bobboau
* added auto-extraction and external loading of textures in VPs, and a user defined temp directory.
*
* Revision 1.8 2007/06/28 11:56:39 kazan
* fix #19
*
* Revision 1.7 2007/03/22 13:15:33 kazan
* MSVC8 compatability checkin, requires wxWidgets 2.8
*
* Revision 1.6 2006/04/09 21:04:10 kazan
* routine checkin
*
* Revision 1.5 2006/04/07 11:57:05 kazan
* sine _WIN32 !defined checks
*
* Revision 1.4 2005/09/19 21:47:12 kazan
* Linux compat changes
*
* Revision 1.3 2005/08/31 15:29:55 kazan
* small behavioral fix for the wildcard search
*
* Revision 1.2 2005/08/31 03:47:40 kazan
* fixed bugs in vpreader, implemented wildcard directory and VP searches, implemented BSP caching, got DDS to work (mostly via a custom compile of DevIL]
*
* Revision 1.1 2005/08/28 00:57:41 kazan
* Initial Import from pcs 1.x - switch to kaz_templates
*
*
*
*/
#if !defined(_WIN32)
#include "compat/filelength.h"
#include "compat/strncmp.h"
#endif
#include "VPReader.h"
#include <cstring>
#include <fstream>
//***********************************************************************************************************************
std::string VolitionPackfileReader::FileName(int fileno)
{
std::string t = Files[fileno].filename;
return t;
}
int VolitionPackfileReader::LoadVPDirectory()
{
VPFile.seekg(0);
VPFile.read((char *) &HeaderData, sizeof(Read_VPHeader));
if (_strnicmp(HeaderData.signature, "VPVP", 4))
return -1; // bad signature
if (HeaderData.version != 2)
return -2; // bad version
VPFile.seekg(0);
VPFile.seekg(HeaderData.diroffset);
Read_VPDirent DirentTemp;
Files.resize(HeaderData.direntries);
int i;
for (i = 0; i < HeaderData.direntries; i++)
{
VPFile.read((char *) &DirentTemp, sizeof(Read_VPDirent));
Files[i] = DirentTemp;
if (VPFile.eof())
break;
}
if (VPFile.eof())
{
if (i < HeaderData.direntries)
HeaderData.direntries = i;
}
VPFile.seekg(0);
return HeaderData.direntries;
}
//***********************************************************************************************************************
int VolitionPackfileReader::FindFileWild(std::string pattern, int start)
{
for (int i = start+1; i < HeaderData.direntries; i++)
{
#ifdef UNIX
#define _strlwr(s) (s)
#endif
if (wildcmp(_strlwr((char*)pattern.c_str()), _strlwr(Files[i].filename)))
#ifdef UNIX
#undef _strlwr
#endif
return i;
}
return -1;
}
//***********************************************************************************************************************
int VolitionPackfileReader::FindFile(std::string filename)
{
for (int i = 0; i < HeaderData.direntries; i++)
{
if (!_strnicmp(filename.c_str(), Files[i].filename, 32))
return i;
}
return -1;
}
//***********************************************************************************************************************
int VolitionPackfileReader::LoadFile(int fileno, boost::scoped_array<char> &membuffer)
{
std::ifstream readfile(lfname.c_str(), std::ios::binary);
if (!readfile)
return -2; //cannot open file
membuffer.reset(NULL);
if (fileno < 0 || fileno > HeaderData.direntries)
return -1; // bad index;
membuffer.reset(new char[Files[fileno].size]);
readfile.seekg(0, std::ios::beg);
readfile.seekg(Files[fileno].offset, std::ios::beg);
readfile.read(membuffer.get(), Files[fileno].size);
readfile.close();
return Files[fileno].size;
}
//***********************************************************************************************************************
bool VolitionPackfileReader::OpenFile(int fileno, std::ifstream &infile)
{
infile.open(lfname.c_str(), std::ios::binary);
infile.seekg(0, std::ios::beg);
infile.seekg(Files[fileno].offset, std::ios::beg);
return true;
}
//***********************************************************************************************************************
bool operator<(Read_VPDirent &lhs, Read_VPDirent &rhs)
{
return lhs.timestamp < rhs.timestamp;
}
//***********************************************************************************************************************
bool operator>(Read_VPDirent &lhs, Read_VPDirent &rhs)
{
return lhs.timestamp > rhs.timestamp;
}
bool VolitionPackfileReader::ReadFromVP(std::string vp, std::string filename, std::string destination)
{
using namespace std;
VolitionPackfileReader VPR(vp);
int filenum = VPR.FindFile(filename);
if (filenum != -1)
{
boost::scoped_array<char> membuffer;
VPR.LoadFile(filenum, membuffer); // loadfile allocates the required size of memory
ofstream outfile(destination.c_str(), ios::out | ios::binary);
outfile.write(membuffer.get(), VPR.FileSize(filenum));
outfile.close();
return true;
}
return false;
}