/[pcsx2_0.9.7]/trunk/plugins/CDVDpeops/ppf.c
ViewVC logotype

Contents of /trunk/plugins/CDVDpeops/ppf.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (show annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (9 years, 11 months ago) by william
File MIME type: text/plain
File size: 7874 byte(s)
committing r3113 initial commit again...
1 /***************************************************************************
2 ppf.c - description
3 -------------------
4 begin : Wed Sep 18 2002
5 copyright : (C) 2002 by Pete Bernert
6 email : BlackDove@addcom.de
7 ***************************************************************************/
8
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. See also the license.txt file for *
15 * additional informations. *
16 * *
17 ***************************************************************************/
18
19 //*************************************************************************//
20 // History of changes:
21 //
22 // 2003/02/14 - Pete
23 // - fixed a bug reading PPF3 patches reported by Zydio
24 //
25 // 2002/09/19 - Pete
26 // - generic cleanup for the Peops release
27 //
28 //*************************************************************************//
29
30 /////////////////////////////////////////////////////////
31
32 #include "stdafx.h"
33 #define _IN_PPF
34 #include "externals.h"
35
36 /////////////////////////////////////////////////////////
37
38 int iUsePPF=0;
39 char szPPF[260];
40 PPF_CACHE * ppfCache=NULL;
41 PPF_DATA * ppfHead=NULL;
42 int iPPFNum=0;
43
44 /////////////////////////////////////////////////////////
45 // works like sub cache... using a linked data list, and address array
46
47 void FillPPFCache(void)
48 {
49 PPF_DATA * p;PPF_CACHE * pc;
50 long lastaddr;
51
52 p=ppfHead;
53 lastaddr=-1;
54 iPPFNum=0;
55
56 while(p)
57 {
58 if(p->addr!=lastaddr) iPPFNum++;
59 lastaddr=p->addr;
60 p=(PPF_DATA *)p->pNext;
61 }
62
63 if(!iPPFNum) return;
64
65 pc=ppfCache=(PPF_CACHE *)malloc(iPPFNum*sizeof(PPF_CACHE));
66
67 iPPFNum--;
68 p=ppfHead;
69 lastaddr=-1;
70
71 while(p)
72 {
73 if(p->addr!=lastaddr)
74 {
75 pc->addr=p->addr;
76 pc->pNext=(void *)p;
77 pc++;
78 }
79 lastaddr=p->addr;
80 p=(PPF_DATA *)p->pNext;
81 }
82 }
83
84 /////////////////////////////////////////////////////////
85
86 void FreePPFCache(void)
87 {
88 PPF_DATA * p=ppfHead;
89 void * pn;
90
91 while(p)
92 {
93 pn=p->pNext;
94 free(p);
95 p=(PPF_DATA *)pn;
96 }
97 ppfHead=NULL;
98
99 if(ppfCache) free(ppfCache);
100 ppfCache=NULL;
101 }
102
103 /////////////////////////////////////////////////////////
104
105 void CheckPPFCache(long addr,unsigned char * pB)
106 {
107 PPF_CACHE * pcstart, * pcend, * pcpos;
108
109 pcstart=ppfCache;
110 if(addr<pcstart->addr) return;
111 pcend=ppfCache+iPPFNum;
112 if(addr>pcend->addr) return;
113
114 while(1)
115 {
116 if(addr==pcend->addr) {pcpos=pcend;break;}
117
118 pcpos=pcstart+(pcend-pcstart)/2;
119 if(pcpos==pcstart) break;
120 if(addr<pcpos->addr)
121 {
122 pcend=pcpos;
123 continue;
124 }
125 if(addr>pcpos->addr)
126 {
127 pcstart=pcpos;
128 continue;
129 }
130 break;
131 }
132
133 if(addr==pcpos->addr)
134 {
135 PPF_DATA * p=(PPF_DATA *)pcpos->pNext;
136 while(p && p->addr==addr)
137 {
138 memcpy(pB+p->pos,p+1,p->anz);
139 p=(PPF_DATA *)p->pNext;
140 }
141 }
142 }
143
144 /////////////////////////////////////////////////////////
145
146 void AddToPPF(long ladr,long pos,long anz,char * ppfmem)
147 {
148 if(!ppfHead)
149 {
150 ppfHead=(PPF_DATA *)malloc(sizeof(PPF_DATA)+anz);
151 ppfHead->addr=ladr;
152 ppfHead->pNext=NULL;
153 ppfHead->pos=pos;
154 ppfHead->anz=anz;
155 memcpy(ppfHead+1,ppfmem,anz);
156 iPPFNum=1;
157 }
158 else
159 {
160 PPF_DATA * p=ppfHead;
161 PPF_DATA * plast=NULL;
162 PPF_DATA * padd;
163 while(p)
164 {
165 if(ladr<p->addr) break;
166 if(ladr==p->addr)
167 {
168 while(p && ladr==p->addr && pos>p->pos)
169 {
170 plast=p;
171 p=(PPF_DATA *)p->pNext;
172 }
173 break;
174 }
175 plast=p;
176 p=(PPF_DATA *)p->pNext;
177 }
178 padd=(PPF_DATA *)malloc(sizeof(PPF_DATA)+anz);
179 padd->addr=ladr;
180 padd->pNext=(void *)p;
181 padd->pos=pos;
182 padd->anz=anz;
183 memcpy(padd+1,ppfmem,anz);
184 iPPFNum++;
185 if(plast==NULL)
186 ppfHead=padd;
187 else plast->pNext=(void *)padd;
188 }
189 }
190
191 /////////////////////////////////////////////////////////
192 // build ppf cache, if wanted
193
194 void BuildPPFCache(void)
195 {
196 FILE * ppffile;
197 char buffer[5];
198 char method,undo=0,blockcheck=0;
199 int dizlen, dizyn, dizlensave=0;
200 char ppfmem[512];
201 int count,seekpos, pos;
202 //unsigned char anz;
203 unsigned int anz; // new! avoids stupid overflows
204 long ladr,off,anx;
205
206 ppfHead=NULL;
207
208 if(iUsePPF==0) return; // no ppf cache wanted?
209 if(szPPF[0]==0) return; // no ppf file given?
210
211 ppffile=fopen(szPPF, "rb");
212 if(ppffile==0)
213 {
214 MessageBox(NULL,"No PPF file found!",libraryName,MB_OK);
215 return;
216 }
217
218 memset(buffer,0,5);
219 fread(buffer, 3, 1, ppffile);
220
221 if(strcmp(buffer,"PPF"))
222 {
223 MessageBox(NULL,"No PPF file format!",libraryName,MB_OK);
224 fclose(ppffile);
225 return;
226 }
227
228 fseek(ppffile, 5, SEEK_SET);
229 fread(&method, 1, 1,ppffile);
230
231 switch(method)
232 {
233 case 0: // ppf1
234 fseek(ppffile, 0, SEEK_END);
235 count=ftell(ppffile);
236 count-=56;
237 seekpos=56;
238 break;
239
240 case 1: // ppf2
241 fseek(ppffile, -8,SEEK_END);
242
243 memset(buffer,0,5);
244 fread(buffer, 4, 1,ppffile);
245 if(strcmp(".DIZ", buffer))
246 {
247 dizyn=0;
248 }
249 else
250 {
251 fread(&dizlen, 4, 1, ppffile);
252 dizyn=1;
253 dizlensave=dizlen;
254 }
255
256 fseek(ppffile, 56, SEEK_SET);
257 fread(&dizlen, 4, 1,ppffile);
258 fseek(ppffile, 0, SEEK_END);
259 count=ftell(ppffile);
260 if(dizyn==0)
261 {
262 count-=1084;
263 seekpos=1084;
264 }
265 else
266 {
267 count-=1084;
268 count-=38;
269 count-=dizlensave;
270 seekpos=1084;
271 }
272 break;
273
274 case 2: // ppf3
275 fseek(ppffile, 57, SEEK_SET);
276 fread(&blockcheck, 1, 1,ppffile);
277 fseek(ppffile, 58, SEEK_SET);
278 fread(&undo, 1, 1,ppffile);
279
280 fseek(ppffile, -6,SEEK_END);
281 memset(buffer,0,5);
282 fread(buffer, 4, 1,ppffile);
283 dizlen=0;
284 if(!strcmp(".DIZ", buffer))
285 {
286 fseek(ppffile, -2,SEEK_END);
287 fread(&dizlen, 2, 1, ppffile);
288 dizlen+=36;
289 }
290
291 fseek(ppffile, 0, SEEK_END);
292 count=ftell(ppffile);
293 count-=dizlen;
294
295 if(blockcheck)
296 {
297 seekpos=1084;
298 count-=1084;
299 }
300 else
301 {
302 seekpos=60;
303 count-=60;
304 }
305
306 break;
307
308 default:
309 fclose(ppffile);
310 MessageBox(NULL,"Unknown PPF format!",libraryName,MB_OK);
311 return;
312 }
313
314 do // now do the data reading
315 {
316 fseek(ppffile, seekpos, SEEK_SET);
317 fread(&pos, 4, 1, ppffile);
318
319 if(method==2) fread(buffer, 4, 1, ppffile); // skip 4 bytes on ppf3 (no int64 support here)
320
321 anz=0; // new! init anz (since it's no unsigned char anymore)
322 fread(&anz, 1, 1, ppffile);
323 fread(ppfmem, anz, 1, ppffile);
324
325 ladr=pos/2352;
326 off=pos%2352;
327
328 if(off+anz>2352)
329 {
330 anx=off+anz-2352;
331 anz-=(unsigned char)anx;
332 AddToPPF(ladr+1,0,anx,ppfmem+anz);
333 }
334
335 AddToPPF(ladr,off,anz,ppfmem); // add to link list
336
337 if(method==2) // adjust ppf3 size
338 {
339 if(undo) anz+=anz;
340 anz+=4;
341 }
342
343 seekpos=seekpos+5+anz;
344 count=count-5-anz;
345 }
346 while(count!=0); // loop til end
347
348 fclose(ppffile);
349
350 FillPPFCache(); // build address array
351 }
352
353 /////////////////////////////////////////////////////////

  ViewVC Help
Powered by ViewVC 1.1.22