]> 4ch.mooo.com Git - 16.git/blob - 16/v2/source/ENGINE/VFILE.C
attempted font system added
[16.git] / 16 / v2 / source / ENGINE / VFILE.C
1 /*\r
2 Copyright (C) 1998 BJ Eirich (aka vecna)\r
3 This program is free software; you can redistribute it and/or\r
4 modify it under the terms of the GNU General Public License\r
5 as published by the Free Software Foundation; either version 2\r
6 of the License, or (at your option) any later version.\r
7 This program is distributed in the hope that it will be useful,\r
8 but WITHOUT ANY WARRANTY; without even the implied warranty of\r
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\r
10 See the GNU General Public Lic\r
11 See the GNU General Public License for more details.\r
12 You should have received a copy of the GNU General Public License\r
13 along with this program; if not, write to the Free Software\r
14 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
15 */\r
16 \r
17 #define VFILE_H\r
18 #define VC_H\r
19 #include "verge.h"\r
20 \r
21 // ================================= Data ====================================\r
22 \r
23 typedef struct\r
24 {\r
25   FILE *fp;                           // real file pointer.\r
26   byte s;                             // 0=real file 1=vfile;\r
27   byte v;                             // if vfile, which vfile index\r
28   byte i;                             // which file index in vfile is it?\r
29   byte p;                             // data alignment pad. :)\r
30 } VFILE;\r
31 \r
32 struct filestruct\r
33 {\r
34   char fname[84];                     // pathname thingo\r
35   int size;                           // size of the file\r
36   int packofs;                        // where the file can be found in PACK\r
37   int curofs;                         // current file offset.\r
38   char extractable;                   // irrelevant to runtime, but...\r
39   char override;                      // should we override?\r
40 };\r
41 \r
42 struct mountstruct\r
43 {\r
44   char mountname[80];                 // name of VRG packfile.\r
45   FILE *vhandle;                      // Real file-handle of packfile.\r
46   struct filestruct *files;           // File record array.\r
47   int numfiles;                       // number of files in pack.\r
48   int curofs;                         // Current filepointer.\r
49 };\r
50 \r
51 struct mountstruct pack[3];            // packfile structs\r
52 byte filesmounted=0;                   // Number of VRG files to check.\r
53 char headertag[]={ 'V','R','G','P','A','C','K',0 };\r
54 \r
55 // ================================= Code ====================================\r
56 \r
57 int Exist(char *fname)\r
58 { FILE *tempf;\r
59 \r
60   tempf=fopen(fname,"rb");\r
61   if (tempf)\r
62   {\r
63      fclose(tempf);\r
64      return 1;\r
65   }\r
66   else return 0;\r
67 }\r
68 \r
69 void DecryptHeader()\r
70 { byte lastvalue, precodebyte, *ptr;\r
71 \r
72   ptr=(byte *) pack[filesmounted].files;\r
73   lastvalue=*ptr;\r
74   ptr++;\r
75 \r
76   while (ptr < (byte *) (int) pack[filesmounted].files + (int) pack[filesmounted].numfiles*100)\r
77   {\r
78     precodebyte=*ptr;\r
79     (*ptr)-=lastvalue;\r
80     lastvalue=precodebyte;\r
81     ptr++;\r
82   }\r
83 }\r
84 \r
85 void MountVFile(char *fname)\r
86 { char buffer[10];\r
87 \r
88   if (!(pack[filesmounted].vhandle = fopen(fname,"rb")))\r
89   {\r
90     printf("*error* Unable to mount %s; file not found. \n",fname);\r
91     exit(-1);\r
92   }\r
93 \r
94   // Read pack header\r
95   memset(&buffer, 0, 10);\r
96   fread(&buffer, 1, 7, pack[filesmounted].vhandle);\r
97   if (strcmp(buffer,headertag))\r
98   {\r
99     printf("*error* %s is not a valid packfile. \n",fname);\r
100     exit(-1);\r
101   }\r
102 \r
103   fread(&buffer, 1, 1, pack[filesmounted].vhandle);\r
104   if (buffer[0]!=1)\r
105   {\r
106     printf("*error* %s is an incompatible packfile version. (ver reported: %d) \n",fname,buffer[0]);\r
107     exit (-1);\r
108   }\r
109 \r
110   fread(&pack[filesmounted].numfiles, 1, 4, pack[filesmounted].vhandle);\r
111   memcpy(pack[filesmounted].mountname,fname,strlen(fname)+1);\r
112 \r
113   // Allocate memory for headers and read them in.\r
114 \r
115   pack[filesmounted].files = (struct filestruct *) valloc(pack[filesmounted].numfiles*100, "pack[filesmounted].files", OID_VFILE);\r
116   fread(pack[filesmounted].files, pack[filesmounted].numfiles, 100, pack[filesmounted].vhandle);\r
117   DecryptHeader();\r
118   filesmounted++;\r
119 }\r
120 \r
121 VFILE *vopen(char *fname)\r
122 { VFILE *tmp;\r
123   char rf=0,vf=0;\r
124   int i, j=0;\r
125 \r
126   // All files using V* are read-only. To write a file, use regular i/o.\r
127   // First we'll see if a real file exists, then we'll check for one in VFiles,\r
128   // if we don't find one in VFile or it's overridable then a real file will\r
129   // be used. That's the general logic progression.\r
130 \r
131   if (Exist(fname)) rf=1;\r
132 \r
133   // Search the VFiles.\r
134   for (i=filesmounted-1; i>=0; i--)\r
135   {\r
136     for (j=0; j<pack[i].numfiles; j++)\r
137         if (!strcasecmp(fname,pack[i].files[j].fname)) { vf=1; break; }\r
138     if (vf) break;\r
139   }\r
140 \r
141   if (!vf && !rf) return 0;\r
142 \r
143   tmp=(VFILE *) valloc(sizeof(VFILE), "vopen:tmp", OID_VFILE);\r
144 \r
145   if (vf && rf)\r
146   {\r
147     if (pack[i].files[j].override) vf=0;\r
148     else rf=0;\r
149   }\r
150 \r
151   if (vf)\r
152   {\r
153     tmp->fp=pack[i].vhandle;\r
154     tmp->s=1;\r
155     tmp->v=i;\r
156     tmp->i=j;\r
157     pack[i].files[j].curofs=0;\r
158     fseek(tmp->fp, pack[i].files[j].packofs, 0);\r
159     pack[i].curofs=pack[i].files[j].packofs;\r
160     return tmp;\r
161   }\r
162 \r
163   tmp->fp=fopen(fname,"rb");\r
164   tmp->s=0; tmp->v=0; tmp->i=0;\r
165   return tmp;\r
166 }\r
167 \r
168 void vread(char *dest, int len, VFILE *f)\r
169 {\r
170   // This is fairly simple.. Just make sure our filepointer is at the right\r
171   // place, then do a straight fread.\r
172 \r
173   if (f->s)\r
174   {\r
175     if (pack[f->v].curofs != (pack[f->v].files[f->i].packofs + pack[f->v].files[f->i].curofs))\r
176        fseek(f->fp, pack[f->v].files[f->i].curofs+pack[f->v].files[f->i].packofs, 0);\r
177     pack[f->v].files[f->i].curofs+=len;\r
178     pack[f->v].curofs+=len;\r
179   }\r
180   fread(dest, 1, len, f->fp);\r
181 }\r
182 \r
183 void vclose(VFILE *f)\r
184 {\r
185   if (!f) return;\r
186   if (!f->s) fclose(f->fp);\r
187   f->fp=0;\r
188   vfree(f);\r
189 }\r
190 \r
191 int filesize(VFILE *f)\r
192 {\r
193   int oldpos, tmp;\r
194 \r
195   // Filesize for Vfiles is real simple.\r
196   if (f->s) return pack[f->v].files[f->i].size;\r
197 \r
198   // It's a bit more complex for external files.\r
199   oldpos=ftell(f->fp);\r
200   fseek(f->fp, 0, 2);\r
201   tmp=ftell(f->fp);\r
202   fseek(f->fp, oldpos, 0);\r
203   return tmp;\r
204 }\r
205 \r
206 int vtell(VFILE *f)\r
207 {\r
208   if (!f->s)\r
209   {\r
210     return ftell(f->fp);\r
211   }\r
212 \r
213   return pack[f->v].files[f->i].curofs;\r
214 }\r
215 \r
216 void vseek(VFILE *f, int offset, int origin)\r
217 {\r
218   if (!f->s)\r
219   {\r
220     fseek(f->fp, offset, origin);\r
221     return;\r
222   }\r
223 \r
224   switch(origin)\r
225   {\r
226     case 0: pack[f->v].files[f->i].curofs=offset;\r
227             fseek(f->fp, offset+pack[f->v].files[f->i].packofs, 0);\r
228             return;\r
229     case 1: pack[f->v].files[f->i].curofs+=offset;\r
230             fseek(f->fp, offset, 1);\r
231             return;\r
232     case 2: pack[f->v].files[f->i].curofs=pack[f->v].files[f->i].size-offset;\r
233             fseek(f->fp, pack[f->v].files[f->i].curofs+pack[f->v].files[f->i].packofs, 0);\r
234             return;\r
235   }\r
236 }\r
237 \r
238 void _vscanf(VFILE *f, char *format, char *dest)\r
239 {\r
240   fscanf(f->fp, format, dest);\r
241   if (f->s)\r
242     pack[f->v].files[f->i].curofs=ftell(f->fp)-pack[f->v].files[f->i].packofs;\r
243 }\r
244 \r
245 char vgetc(VFILE *f)\r
246 { char c=0;\r
247 \r
248   vread(&c, 1, f);\r
249   return c;\r
250 }\r
251 \r
252 word vgetw(VFILE *f)\r
253 { word c=0;\r
254 \r
255   vread((char *) &c, 2, f);\r
256   return c;\r
257 }\r
258 \r
259 void vgets(char *str, int len, VFILE *f)\r
260 {\r
261   if (f->s)\r
262   {\r
263     if (pack[f->v].curofs != (pack[f->v].files[f->i].packofs + pack[f->v].files[f->i].curofs))\r
264        fseek(f->fp, pack[f->v].files[f->i].curofs+pack[f->v].files[f->i].packofs, 0);\r
265     pack[f->v].files[f->i].curofs+=len;\r
266     pack[f->v].curofs+=len;\r
267   }\r
268   fgets(str, len, f->fp);\r
269 }\r