/[pcsx2_0.9.7]/trunk/pcsx2/CDVD/CDVDaccess.cpp
ViewVC logotype

Annotation of /trunk/pcsx2/CDVD/CDVDaccess.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 273 - (hide annotations) (download)
Fri Nov 12 01:10:22 2010 UTC (10 years, 5 months ago) by william
File size: 12022 byte(s)
Auto Commited Import of: pcsx2-0.9.7-DEBUG (upstream: v0.9.7.4013 local: v0.9.7.197-latest) in ./trunk
1 william 31 /* PCSX2 - PS2 Emulator for PCs
2     * Copyright (C) 2002-2010 PCSX2 Dev Team
3     *
4     * PCSX2 is free software: you can redistribute it and/or modify it under the terms
5     * of the GNU Lesser General Public License as published by the Free Software Found-
6     * ation, either version 3 of the License, or (at your option) any later version.
7     *
8     * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9     * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10     * PURPOSE. See the GNU General Public License for more details.
11     *
12     * You should have received a copy of the GNU General Public License along with PCSX2.
13     * If not, see <http://www.gnu.org/licenses/>.
14     */
15    
16    
17     #include "PrecompiledHeader.h"
18     #include "IopCommon.h"
19    
20     #define ENABLE_TIMESTAMPS
21    
22     #ifdef _WIN32
23     # include <wx/msw/wrapwin.h>
24     #endif
25    
26     #include <ctype.h>
27     #include <time.h>
28     #include <wx/datetime.h>
29     #include <exception>
30    
31     #include "IsoFS/IsoFS.h"
32     #include "IsoFS/IsoFSCDVD.h"
33     #include "CDVDisoReader.h"
34     #include "Utilities/ScopedPtr.h"
35    
36     const wxChar* CDVD_SourceLabels[] =
37     {
38     L"Iso",
39     L"Plugin",
40     L"NoDisc",
41     NULL
42     };
43    
44     // ----------------------------------------------------------------------------
45     // diskTypeCached
46     // Internal disc type cache, to reduce the overhead of disc type checks, which are
47     // performed quite liberally by many games (perhaps intended to keep the PS2 DVD
48     // from spinning down due to idle activity?).
49     // Cache is set to -1 for init and when the disc is removed/changed, which invokes
50     // a new DiskTypeCheck. All subsequent checks use the non-negative value here.
51     //
52     static int diskTypeCached = -1;
53    
54     // used to bridge the gap between the old getBuffer api and the new getBuffer2 api.
55     int lastReadSize;
56     int lastLSN; // needed for block dumping
57    
58     // Records last read block length for block dumping
59     //static int plsn = 0;
60 william 273 static isoFile blockDumpFile;
61 william 31
62     // Assertion check for CDVD != NULL (in devel and debug builds), because its handier than
63     // relying on DEP exceptions -- and a little more reliable too.
64     static void CheckNullCDVD()
65     {
66     pxAssertDev( CDVD != NULL, "Invalid CDVD object state (null pointer exception)" );
67     }
68    
69     //////////////////////////////////////////////////////////////////////////////////////////
70     // Disk Type detection stuff (from cdvdGigaherz)
71     //
72     static int CheckDiskTypeFS(int baseType)
73     {
74     IsoFSCDVD isofs;
75     IsoDirectory rootdir(isofs);
76     try {
77     IsoFile file( rootdir, L"SYSTEM.CNF;1");
78    
79     int size = file.getLength();
80    
81     ScopedArray<char> buffer((int)file.getLength()+1);
82     file.read((u8*)(buffer.GetPtr()),size);
83     buffer[size]='\0';
84    
85     char* pos = strstr(buffer.GetPtr(), "BOOT2");
86     if (pos == NULL)
87     {
88     pos = strstr(buffer.GetPtr(), "BOOT");
89     if (pos == NULL) return CDVD_TYPE_ILLEGAL;
90     return CDVD_TYPE_PSCD;
91     }
92    
93     return (baseType==CDVD_TYPE_DETCTCD) ? CDVD_TYPE_PS2CD : CDVD_TYPE_PS2DVD;
94     }
95     catch( Exception::FileNotFound& )
96     {
97     }
98    
99     try {
100     IsoFile file( rootdir, L"PSX.EXE;1");
101     return CDVD_TYPE_PSCD;
102     }
103     catch( Exception::FileNotFound& )
104     {
105     }
106    
107     try {
108     IsoFile file( rootdir, L"VIDEO_TS/VIDEO_TS.IFO;1");
109     return CDVD_TYPE_DVDV;
110     }
111     catch( Exception::FileNotFound& )
112     {
113     }
114    
115     return CDVD_TYPE_ILLEGAL; // << Only for discs which aren't ps2 at all.
116     }
117    
118     static int FindDiskType(int mType)
119     {
120     int dataTracks = 0;
121     int audioTracks = 0;
122     int iCDType = mType;
123     cdvdTN tn;
124    
125     CDVD->getTN(&tn);
126    
127     if (tn.strack != tn.etrack) // multitrack == CD.
128     {
129     iCDType = CDVD_TYPE_DETCTCD;
130     }
131     else if (mType < 0)
132     {
133     static u8 bleh[CD_FRAMESIZE_RAW];
134     cdvdTD td;
135    
136     CDVD->getTD(0,&td);
137     if (td.lsn > 452849)
138     {
139     iCDType = CDVD_TYPE_DETCTDVDS;
140     }
141     else
142     {
143     if (DoCDVDreadSector(bleh, 16, CDVD_MODE_2048) == 0)
144     {
145     //const cdVolDesc& volDesc = (cdVolDesc&)bleh;
146     //if(volDesc.rootToc.tocSize == 2048)
147     if(*(u16*)(bleh+166) == 2048)
148     iCDType = CDVD_TYPE_DETCTCD;
149     else
150     iCDType = CDVD_TYPE_DETCTDVDS;
151     }
152     }
153     }
154    
155     if (iCDType == CDVD_TYPE_DETCTDVDS)
156     {
157     s32 dlt = 0;
158     u32 l1s = 0;
159    
160     if(CDVD->getDualInfo(&dlt,&l1s)==0)
161     {
162     if (dlt > 0) iCDType = CDVD_TYPE_DETCTDVDD;
163     }
164     }
165    
166     switch(iCDType)
167     {
168     case CDVD_TYPE_DETCTCD:
169     Console.WriteLn(" * CDVD Disk Open: CD, %d tracks (%d to %d):", tn.etrack-tn.strack+1,tn.strack,tn.etrack);
170     break;
171    
172     case CDVD_TYPE_DETCTDVDS:
173     Console.WriteLn(" * CDVD Disk Open: DVD, Single layer or unknown:");
174     break;
175    
176     case CDVD_TYPE_DETCTDVDD:
177     Console.WriteLn(" * CDVD Disk Open: DVD, Double layer:");
178     break;
179     }
180    
181     audioTracks = dataTracks = 0;
182     for(int i = tn.strack; i <= tn.etrack; i++)
183     {
184     cdvdTD td,td2;
185    
186     CDVD->getTD(i,&td);
187    
188     if (tn.etrack > i)
189     CDVD->getTD(i+1,&td2);
190     else
191     CDVD->getTD(0,&td2);
192    
193     int tlength = td2.lsn - td.lsn;
194    
195     if (td.type == CDVD_AUDIO_TRACK)
196     {
197     audioTracks++;
198     Console.WriteLn(" * * Track %d: Audio (%d sectors)", i,tlength);
199     }
200     else
201     {
202     dataTracks++;
203     Console.WriteLn(" * * Track %d: Data (Mode %d) (%d sectors)", i,((td.type==CDVD_MODE1_TRACK)?1:2),tlength);
204     }
205     }
206    
207     if (dataTracks > 0)
208     {
209     iCDType=CheckDiskTypeFS(iCDType);
210     }
211    
212     if (audioTracks > 0)
213     {
214     switch (iCDType)
215     {
216     case CDVD_TYPE_PS2CD:
217     iCDType=CDVD_TYPE_PS2CDDA;
218     break;
219     case CDVD_TYPE_PSCD:
220     iCDType=CDVD_TYPE_PSCDDA;
221     break;
222     default:
223     iCDType=CDVD_TYPE_CDDA;
224     break;
225     }
226     }
227    
228     return iCDType;
229     }
230    
231     static void DetectDiskType()
232     {
233     if (CDVD->getTrayStatus() == CDVD_TRAY_OPEN)
234     {
235     diskTypeCached = CDVD_TYPE_NODISC;
236     return;
237     }
238    
239     int baseMediaType = CDVD->getDiskType();
240     int mType = -1;
241    
242     // Paranoid mode: do not trust the plugin's detection system to work correctly.
243     // (.. and there's no reason plugins should be doing their own detection anyway).
244    
245     switch(baseMediaType)
246     {
247     #if 0
248     case CDVD_TYPE_CDDA:
249     case CDVD_TYPE_PSCD:
250     case CDVD_TYPE_PS2CD:
251     case CDVD_TYPE_PSCDDA:
252     case CDVD_TYPE_PS2CDDA:
253     mType = CDVD_TYPE_DETCTCD;
254     break;
255    
256     case CDVD_TYPE_DVDV:
257     case CDVD_TYPE_PS2DVD:
258     mType = CDVD_TYPE_DETCTDVDS;
259     break;
260    
261     case CDVD_TYPE_DETCTDVDS:
262     case CDVD_TYPE_DETCTDVDD:
263     case CDVD_TYPE_DETCTCD:
264     mType = baseMediaType;
265     break;
266     #endif
267    
268     case CDVD_TYPE_NODISC:
269     diskTypeCached = CDVD_TYPE_NODISC;
270     return;
271     }
272    
273     diskTypeCached = FindDiskType(mType);
274     }
275    
276     static wxString m_SourceFilename[3];
277     static CDVD_SourceType m_CurrentSourceType = CDVDsrc_NoDisc;
278    
279     void CDVDsys_SetFile( CDVD_SourceType srctype, const wxString& newfile )
280     {
281     m_SourceFilename[srctype] = newfile;
282     }
283    
284     const wxString& CDVDsys_GetFile( CDVD_SourceType srctype )
285     {
286     return m_SourceFilename[srctype];
287     }
288    
289     CDVD_SourceType CDVDsys_GetSourceType()
290     {
291     return m_CurrentSourceType;
292     }
293    
294     void CDVDsys_ChangeSource( CDVD_SourceType type )
295     {
296     GetCorePlugins().Close( PluginId_CDVD );
297 william 62
298     static bool firstRun = true;
299     if (!firstRun) cdvdCtrlTrayOpen();
300     firstRun = false;
301    
302 william 31 switch( m_CurrentSourceType = type )
303     {
304     case CDVDsrc_Iso:
305     CDVD = &CDVDapi_Iso;
306     break;
307    
308     case CDVDsrc_NoDisc:
309     CDVD = &CDVDapi_NoDisc;
310     break;
311    
312     case CDVDsrc_Plugin:
313     CDVD = &CDVDapi_Plugin;
314     break;
315    
316     jNO_DEFAULT;
317     }
318     }
319    
320     bool DoCDVDopen()
321     {
322     CheckNullCDVD();
323    
324     // the new disk callback is set on Init also, but just in case the plugin clears it for
325     // some reason on close, we re-send here:
326     CDVD->newDiskCB( cdvdNewDiskCB );
327    
328     // Win32 Fail: the old CDVD api expects MBCS on Win32 platforms, but generating a MBCS
329     // from unicode is problematic since we need to know the codepage of the text being
330     // converted (which isn't really practical knowledge). A 'best guess' would be the
331     // default codepage of the user's Windows install, but even that will fail and return
332     // question marks if the filename is another language.
333     // Likely Fix: Force new versions of CDVD plugins to expect UTF8 instead.
334    
335     int ret = CDVD->open( !m_SourceFilename[m_CurrentSourceType].IsEmpty() ?
336     m_SourceFilename[m_CurrentSourceType].ToUTF8() : (char*)NULL
337     );
338    
339 william 62 if( ret == -1 ) return false; // error! (handled by caller)
340     if( ret == 1 ) throw Exception::CancelEvent(L"User canceled the CDVD plugin's open dialog.");
341 william 31
342     int cdtype = DoCDVDdetectDiskType();
343    
344 william 273 if (!EmuConfig.CdvdDumpBlocks || (cdtype == CDVD_TYPE_NODISC))
345 william 31 {
346 william 273 blockDumpFile.Close();
347     return true;
348     }
349 william 31
350 william 273 // TODO: Add a blockdumps configurable folder, and use that instead of CWD().
351 william 31
352 william 273 // TODO: "Untitled" should use pnach/slus name resolution, slus if no patch,
353     // and finally an "Untitled-[ElfCRC]" if no slus.
354 william 31
355 william 273 wxString somepick( Path::GetFilenameWithoutExt( m_SourceFilename[m_CurrentSourceType] ) );
356     if( somepick.IsEmpty() )
357     somepick = L"Untitled";
358 william 31
359 william 273 wxString temp( Path::Combine( wxGetCwd(), somepick ) );
360    
361 william 31 #ifdef ENABLE_TIMESTAMPS
362 william 273 wxDateTime curtime( wxDateTime::GetTimeNow() );
363 william 31
364 william 273 temp += pxsFmt( L" (%04d-%02d-%02d %02d-%02d-%02d)",
365     curtime.GetYear(), curtime.GetMonth(), curtime.GetDay(),
366     curtime.GetHour(), curtime.GetMinute(), curtime.GetSecond()
367     );
368 william 31 #endif
369 william 273 temp += L".dump";
370 william 31
371 william 273 cdvdTD td;
372     CDVD->getTD(0, &td);
373 william 31
374 william 273 blockDumpFile.Create(temp, ISOFLAGS_BLOCKDUMP_V3);
375 william 31
376 william 273 if( blockDumpFile.IsOpened() )
377     {
378     int blockofs = 0;
379     uint blocksize = CD_FRAMESIZE_RAW;
380     uint blocks = td.lsn;
381 william 31
382 william 273 // hack: Because of limitations of the current cdvd design, we can't query the blocksize
383     // of the underlying media. So lets make a best guess:
384 william 31
385 william 273 switch(cdtype)
386     {
387     case CDVD_TYPE_PS2DVD:
388     case CDVD_TYPE_DVDV:
389     case CDVD_TYPE_DETCTDVDS:
390     case CDVD_TYPE_DETCTDVDD:
391     blocksize = 2048;
392     break;
393 william 31 }
394 william 273 blockDumpFile.WriteFormat(blockofs, blocksize, blocks);
395 william 31 }
396    
397     return true;
398     }
399    
400     void DoCDVDclose()
401     {
402     CheckNullCDVD();
403 william 273 blockDumpFile.Close();
404    
405 william 31 if( CDVD->close != NULL )
406     CDVD->close();
407    
408     DoCDVDresetDiskTypeCache();
409     }
410    
411     s32 DoCDVDreadSector(u8* buffer, u32 lsn, int mode)
412     {
413     CheckNullCDVD();
414     int ret = CDVD->readSector(buffer,lsn,mode);
415    
416 william 273 if (ret == 0 && blockDumpFile.IsOpened())
417 william 31 {
418 william 273 blockDumpFile.WriteBlock(buffer, lsn);
419 william 31 }
420    
421     return ret;
422     }
423    
424     s32 DoCDVDreadTrack(u32 lsn, int mode)
425     {
426     CheckNullCDVD();
427    
428     // TEMP: until all the plugins use the new CDVDgetBuffer style
429     switch (mode)
430     {
431     case CDVD_MODE_2352:
432     lastReadSize = 2352;
433     break;
434     case CDVD_MODE_2340:
435     lastReadSize = 2340;
436     break;
437     case CDVD_MODE_2328:
438     lastReadSize = 2328;
439     break;
440     case CDVD_MODE_2048:
441     lastReadSize = 2048;
442     break;
443     }
444    
445     //DevCon.Warning("CDVD readTrack(lsn=%d,mode=%d)",params lsn, lastReadSize);
446     lastLSN = lsn;
447     return CDVD->readTrack(lsn,mode);
448     }
449    
450     s32 DoCDVDgetBuffer(u8* buffer)
451     {
452     CheckNullCDVD();
453     int ret = CDVD->getBuffer2(buffer);
454    
455 william 273 if (ret == 0 && blockDumpFile.IsOpened())
456 william 31 {
457 william 273 blockDumpFile.WriteBlock(buffer, lastLSN);
458 william 31 }
459    
460     return ret;
461     }
462    
463     s32 DoCDVDdetectDiskType()
464     {
465     CheckNullCDVD();
466     if(diskTypeCached < 0) DetectDiskType();
467     return diskTypeCached;
468     }
469    
470     void DoCDVDresetDiskTypeCache()
471     {
472     diskTypeCached = -1;
473     }
474    
475     ////////////////////////////////////////////////////////
476     //
477     // CDVD null interface for Run BIOS menu
478    
479    
480    
481     s32 CALLBACK NODISCopen(const char* pTitle)
482     {
483     return 0;
484     }
485    
486     void CALLBACK NODISCclose()
487     {
488     }
489    
490     s32 CALLBACK NODISCreadTrack(u32 lsn, int mode)
491     {
492     return -1;
493     }
494    
495     // return can be NULL (for async modes)
496     u8* CALLBACK NODISCgetBuffer()
497     {
498     return NULL;
499     }
500    
501     s32 CALLBACK NODISCreadSubQ(u32 lsn, cdvdSubQ* subq)
502     {
503     return -1;
504     }
505    
506     s32 CALLBACK NODISCgetTN(cdvdTN *Buffer)
507     {
508     return -1;
509     }
510    
511     s32 CALLBACK NODISCgetTD(u8 Track, cdvdTD *Buffer)
512     {
513     return -1;
514     }
515    
516     s32 CALLBACK NODISCgetTOC(void* toc)
517     {
518     return -1;
519     }
520    
521     s32 CALLBACK NODISCgetDiskType()
522     {
523     return CDVD_TYPE_NODISC;
524     }
525    
526     s32 CALLBACK NODISCgetTrayStatus()
527     {
528     return CDVD_TRAY_CLOSE;
529     }
530    
531     s32 CALLBACK NODISCdummyS32()
532     {
533     return 0;
534     }
535    
536     void CALLBACK NODISCnewDiskCB(void (* /* callback */)())
537     {
538     }
539    
540     s32 CALLBACK NODISCreadSector(u8* tempbuffer, u32 lsn, int mode)
541     {
542     return -1;
543     }
544    
545     s32 CALLBACK NODISCgetBuffer2(u8* buffer)
546     {
547     return -1;
548     }
549    
550     s32 CALLBACK NODISCgetDualInfo(s32* dualType, u32* _layer1start)
551     {
552     return -1;
553     }
554    
555     CDVD_API CDVDapi_NoDisc =
556     {
557     NODISCclose,
558     NODISCopen,
559     NODISCreadTrack,
560     NODISCgetBuffer,
561     NODISCreadSubQ,
562     NODISCgetTN,
563     NODISCgetTD,
564     NODISCgetTOC,
565     NODISCgetDiskType,
566     NODISCgetTrayStatus,
567     NODISCdummyS32,
568     NODISCdummyS32,
569    
570     NODISCnewDiskCB,
571    
572     NODISCreadSector,
573     NODISCgetBuffer2,
574     NODISCgetDualInfo,
575     };

  ViewVC Help
Powered by ViewVC 1.1.22