PageRenderTime 69ms CodeModel.GetById 31ms RepoModel.GetById 1ms app.codeStats 0ms

/plugins/cdvdGigaherz/src/CDVD.cpp

https://github.com/alexsharoff/pcsx2-online
C++ | 533 lines | 481 code | 35 blank | 17 comment | 2 complexity | 0c7b4a8b2554541a70e454f4197ad973 MD5 | raw file
  1. #include <stdio.h>
  2. #include "CDVD.h"
  3. #include "resource.h"
  4. #include "Shlwapi.h"
  5. #include "svnrev.h"
  6. #include <assert.h>
  7. void (*newDiscCB)();
  8. #define STRFY(x) #x
  9. #define TOSTR(x) STRFY(x)
  10. ///////////////////////////////////////////////////////////////////////////////
  11. ///////////////////////////////////////////////////////////////////////////////
  12. // State Information //
  13. int strack;
  14. int etrack;
  15. track tracks[100];
  16. int curDiskType;
  17. int curTrayStatus;
  18. int csector;
  19. int cmode;
  20. #define SFY(x) STRFY(x)
  21. ///////////////////////////////////////////////////////////////////////////////
  22. ///////////////////////////////////////////////////////////////////////////////
  23. // Plugin Interface //
  24. char *LibName = "cdvdGigaherz "
  25. #ifdef PCSX2_DEBUG
  26. " Debug "
  27. #endif
  28. "(r" SFY(SVN_REV)
  29. #if SVN_MODS
  30. "/modded"
  31. #endif
  32. ")";
  33. const unsigned char version = PS2E_CDVD_VERSION;
  34. const unsigned char revision = 0;
  35. const unsigned char build = 8;
  36. HINSTANCE hinst;
  37. BOOL WINAPI DllMain(
  38. HINSTANCE hinstDLL, // handle to DLL module
  39. DWORD fdwReason, // reason for calling function
  40. LPVOID lpvReserved // reserved
  41. )
  42. {
  43. if(fdwReason==DLL_PROCESS_ATTACH) {
  44. hinst=hinstDLL;
  45. }
  46. return TRUE;
  47. }
  48. char* CALLBACK PS2EgetLibName() {
  49. return LibName;
  50. }
  51. u32 CALLBACK PS2EgetLibType() {
  52. return PS2E_LT_CDVD;
  53. }
  54. u32 CALLBACK PS2EgetLibVersion2(u32 type) {
  55. return (version << 16) | (revision << 8) | build;
  56. }
  57. ///////////////////////////////////////////////////////////////////////////////
  58. ///////////////////////////////////////////////////////////////////////////////
  59. // Utility Functions //
  60. void SysMessage(char *fmt, ...) {
  61. va_list list;
  62. char tmp[512];
  63. va_start(list,fmt);
  64. vsprintf(tmp,fmt,list);
  65. va_end(list);
  66. MessageBox(0, tmp, "cdvdGigaherz Msg", 0);
  67. }
  68. u8 __inline dec_to_bcd(u8 dec)
  69. {
  70. return ((dec/10)<<4)|(dec%10);
  71. }
  72. void __inline lsn_to_msf(u8* minute, u8* second, u8* frame, u32 lsn)
  73. {
  74. *frame = dec_to_bcd(lsn%75);
  75. lsn/=75;
  76. *second= dec_to_bcd(lsn%60);
  77. lsn/=60;
  78. *minute= dec_to_bcd(lsn%100);
  79. }
  80. void __inline lba_to_msf(s32 lba, u8* m, u8* s, u8* f) {
  81. lba += 150;
  82. *m = (u8)(lba / (60*75));
  83. *s = (u8)((lba / 75) % 60);
  84. *f = (u8)(lba % 75);
  85. }
  86. ///////////////////////////////////////////////////////////////////////////////
  87. ///////////////////////////////////////////////////////////////////////////////
  88. // CDVD processing functions //
  89. char csrc[20];
  90. BOOL cdvd_is_open=FALSE;
  91. Source *src;
  92. s32 disc_has_changed=0;
  93. int weAreInNewDiskCB=0;
  94. char bfr[2352];
  95. ///////////////////////////////////////////////////////////////////////////////
  96. ///////////////////////////////////////////////////////////////////////////////
  97. // CDVD Pluin Interface //
  98. void CALLBACK CDVDsetSettingsDir(const char* dir)
  99. {
  100. CfgSetSettingsDir(dir);
  101. }
  102. s32 CALLBACK CDVDinit()
  103. {
  104. return 0;
  105. }
  106. s32 CALLBACK CDVDopen(const char* pTitleFilename)
  107. {
  108. ReadSettings();
  109. if(source_drive=='-')
  110. {
  111. // MSDN : Trailing backslash is required to ensure consistent behavior across
  112. // various versions of Windows and storage types.
  113. char temp[]="A:\\";
  114. for(char d='A';d<='Z';d++)
  115. {
  116. temp[0]=d;
  117. if(GetDriveType(temp)==DRIVE_CDROM)
  118. {
  119. source_drive=d;
  120. break;
  121. }
  122. }
  123. }
  124. if(source_drive=='@')
  125. {
  126. curDiskType=CDVD_TYPE_NODISC;
  127. return 0;
  128. }
  129. if(source_drive=='$')
  130. {
  131. printf(" * CDVD: Opening image '%s'...\n",source_file);
  132. //open device file
  133. src= TryLoaders(source_file);
  134. }
  135. else
  136. {
  137. sprintf(csrc,"\\\\.\\%c:",source_drive);
  138. printf(" * CDVD: Opening drive '%s'...\n",csrc);
  139. //open device file
  140. src=new IOCtlSrc(csrc);
  141. }
  142. if(!src->IsOK())
  143. {
  144. printf(" * CDVD: Error opening source.\n");
  145. return -1;
  146. }
  147. //setup threading manager
  148. cdvdStartThread();
  149. return cdvdRefreshData();
  150. }
  151. void CALLBACK CDVDclose()
  152. {
  153. cdvdStopThread();
  154. //close device
  155. delete src;
  156. src=NULL;
  157. }
  158. void CALLBACK CDVDshutdown()
  159. {
  160. //nothing to do here
  161. }
  162. s32 CALLBACK CDVDgetDualInfo(s32* dualType, u32* _layer1start)
  163. {
  164. switch(src->GetMediaType())
  165. {
  166. case 1:
  167. *dualType = 1;
  168. *_layer1start = src->GetLayerBreakAddress();
  169. return 1;
  170. case 2:
  171. *dualType = 2;
  172. *_layer1start = src->GetLayerBreakAddress();
  173. return 1;
  174. case 0:
  175. *dualType = 0;
  176. *_layer1start = 0;
  177. return 1;
  178. }
  179. return 0;
  180. }
  181. int lastReadInNewDiskCB=0;
  182. char fuckThisSector[2352];
  183. s32 CALLBACK CDVDreadSector(u8* buffer, s32 lsn, int mode)
  184. {
  185. return cdvdDirectReadSector(lsn,mode,(char*)buffer);
  186. }
  187. s32 CALLBACK CDVDreadTrack(u32 lsn, int mode)
  188. {
  189. csector=lsn;
  190. cmode=mode;
  191. if(weAreInNewDiskCB)
  192. {
  193. int ret = cdvdDirectReadSector(lsn,mode,fuckThisSector);
  194. if(ret==0) lastReadInNewDiskCB=1;
  195. return ret;
  196. }
  197. if(lsn>tracks[0].length) // track 0 is total disc.
  198. {
  199. return -1;
  200. }
  201. return cdvdRequestSector(lsn,mode);
  202. }
  203. // return can be NULL (for async modes)
  204. u8* CALLBACK CDVDgetBuffer()
  205. {
  206. if(lastReadInNewDiskCB)
  207. {
  208. lastReadInNewDiskCB=0;
  209. return (u8*)fuckThisSector;
  210. }
  211. u8 *s = (u8*)cdvdGetSector(csector,cmode);
  212. return s;
  213. }
  214. // return can be NULL (for async modes)
  215. int CALLBACK CDVDgetBuffer2(u8* dest)
  216. {
  217. int csize = 2352;
  218. switch(cmode)
  219. {
  220. case CDVD_MODE_2048: csize = 2048; break;
  221. case CDVD_MODE_2328: csize = 2328; break;
  222. case CDVD_MODE_2340: csize = 2340; break;
  223. }
  224. if(lastReadInNewDiskCB)
  225. {
  226. lastReadInNewDiskCB=0;
  227. memcpy(dest, fuckThisSector, csize);
  228. return 0;
  229. }
  230. memcpy(dest, cdvdGetSector(csector,cmode), csize);
  231. return 0;
  232. }
  233. s32 CALLBACK CDVDreadSubQ(u32 lsn, cdvdSubQ* subq)
  234. {
  235. int i;
  236. // the formatted subq command returns: control/adr, track, index, trk min, trk sec, trk frm, 0x00, abs min, abs sec, abs frm
  237. if(lsn>tracks[0].length) // track 0 is total disc.
  238. return -1;
  239. memset(subq,0,sizeof(cdvdSubQ));
  240. lsn_to_msf(&subq->discM,&subq->discS,&subq->discF,lsn+150);
  241. i=strack;
  242. while(i<=etrack)
  243. {
  244. if(lsn<=tracks[i].length)
  245. break;
  246. lsn-=tracks[i].length;
  247. i++;
  248. }
  249. if(i>etrack)
  250. i=etrack;
  251. lsn_to_msf(&subq->trackM,&subq->trackS,&subq->trackF,lsn);
  252. subq->mode=1;
  253. subq->ctrl=tracks[i].type;
  254. subq->trackNum=i;
  255. subq->trackIndex=1;
  256. return 0;
  257. }
  258. s32 CALLBACK CDVDgetTN(cdvdTN *Buffer)
  259. {
  260. Buffer->strack=strack;
  261. Buffer->etrack=etrack;
  262. return 0;
  263. }
  264. s32 CALLBACK CDVDgetTD(u8 Track, cdvdTD *Buffer)
  265. {
  266. if(Track==0)
  267. {
  268. Buffer->lsn = tracks[0].length;
  269. Buffer->type= 0;
  270. return 0;
  271. }
  272. if(Track<strack) return -1;
  273. if(Track>etrack) return -1;
  274. Buffer->lsn = tracks[Track].start_lba;
  275. Buffer->type= tracks[Track].type;
  276. return 0;
  277. }
  278. u32 layer1start=-1;
  279. s32 CALLBACK CDVDgetTOC(u8* tocBuff)
  280. {
  281. //return src->ReadTOC((char*)toc,2048);
  282. //that didn't work too well...
  283. if(curDiskType==CDVD_TYPE_NODISC)
  284. return -1;
  285. if((curDiskType == CDVD_TYPE_DVDV) ||
  286. (curDiskType == CDVD_TYPE_PS2DVD))
  287. {
  288. memset(tocBuff, 0, 2048);
  289. s32 mt=src->GetMediaType();
  290. if(mt<0)
  291. return -1;
  292. if(mt==0) //single layer
  293. {
  294. // fake it
  295. tocBuff[ 0] = 0x04;
  296. tocBuff[ 1] = 0x02;
  297. tocBuff[ 2] = 0xF2;
  298. tocBuff[ 3] = 0x00;
  299. tocBuff[ 4] = 0x86;
  300. tocBuff[ 5] = 0x72;
  301. tocBuff[16] = 0x00; // first sector for layer 0
  302. tocBuff[17] = 0x03;
  303. tocBuff[18] = 0x00;
  304. tocBuff[19] = 0x00;
  305. }
  306. else if(mt==1) //PTP
  307. {
  308. layer1start = src->GetLayerBreakAddress() + 0x30000;
  309. // dual sided
  310. tocBuff[ 0] = 0x24;
  311. tocBuff[ 1] = 0x02;
  312. tocBuff[ 2] = 0xF2;
  313. tocBuff[ 3] = 0x00;
  314. tocBuff[ 4] = 0x41;
  315. tocBuff[ 5] = 0x95;
  316. tocBuff[14] = 0x61; // PTP
  317. tocBuff[16] = 0x00;
  318. tocBuff[17] = 0x03;
  319. tocBuff[18] = 0x00;
  320. tocBuff[19] = 0x00;
  321. tocBuff[20] = (layer1start>>24);
  322. tocBuff[21] = (layer1start>>16)&0xff;
  323. tocBuff[22] = (layer1start>> 8)&0xff;
  324. tocBuff[23] = (layer1start>> 0)&0xff;
  325. }
  326. else //OTP
  327. {
  328. layer1start = src->GetLayerBreakAddress() + 0x30000;
  329. // dual sided
  330. tocBuff[ 0] = 0x24;
  331. tocBuff[ 1] = 0x02;
  332. tocBuff[ 2] = 0xF2;
  333. tocBuff[ 3] = 0x00;
  334. tocBuff[ 4] = 0x41;
  335. tocBuff[ 5] = 0x95;
  336. tocBuff[14] = 0x71; // OTP
  337. tocBuff[16] = 0x00;
  338. tocBuff[17] = 0x03;
  339. tocBuff[18] = 0x00;
  340. tocBuff[19] = 0x00;
  341. tocBuff[24] = (layer1start>>24);
  342. tocBuff[25] = (layer1start>>16)&0xff;
  343. tocBuff[26] = (layer1start>> 8)&0xff;
  344. tocBuff[27] = (layer1start>> 0)&0xff;
  345. }
  346. }
  347. else if(curDiskType == CDVD_TYPE_CDDA ||
  348. curDiskType == CDVD_TYPE_PS2CDDA ||
  349. curDiskType == CDVD_TYPE_PS2CD ||
  350. curDiskType == CDVD_TYPE_PSCDDA ||
  351. curDiskType == CDVD_TYPE_PSCD)
  352. {
  353. // cd toc
  354. // (could be replaced by 1 command that reads the full toc)
  355. u8 min, sec, frm,i;
  356. s32 err;
  357. cdvdTN diskInfo;
  358. cdvdTD trackInfo;
  359. memset(tocBuff, 0, 1024);
  360. if (CDVDgetTN(&diskInfo) == -1) { diskInfo.etrack = 0;diskInfo.strack = 1; }
  361. if (CDVDgetTD(0, &trackInfo) == -1) trackInfo.lsn = 0;
  362. tocBuff[0] = 0x41;
  363. tocBuff[1] = 0x00;
  364. #define itob(n) ((((n)/10)<<4)+((n)%10))
  365. //Number of FirstTrack
  366. tocBuff[2] = 0xA0;
  367. tocBuff[7] = itob(diskInfo.strack);
  368. //Number of LastTrack
  369. tocBuff[12] = 0xA1;
  370. tocBuff[17] = itob(diskInfo.etrack);
  371. //DiskLength
  372. lba_to_msf(trackInfo.lsn, &min, &sec, &frm);
  373. tocBuff[22] = 0xA2;
  374. tocBuff[27] = itob(min);
  375. tocBuff[28] = itob(sec);
  376. tocBuff[29] = itob(frm);
  377. fprintf(stderr,"Track 0: %d mins %d secs %d frames\n",min,sec,frm);
  378. for (i=diskInfo.strack; i<=diskInfo.etrack; i++)
  379. {
  380. err = CDVDgetTD(i, &trackInfo);
  381. lba_to_msf(trackInfo.lsn, &min, &sec, &frm);
  382. tocBuff[i*10+30] = trackInfo.type;
  383. tocBuff[i*10+32] = err == -1 ? 0 : itob(i); //number
  384. tocBuff[i*10+37] = itob(min);
  385. tocBuff[i*10+38] = itob(sec);
  386. tocBuff[i*10+39] = itob(frm);
  387. fprintf(stderr,"Track %d: %d mins %d secs %d frames\n",i,min,sec,frm);
  388. }
  389. }
  390. else
  391. return -1;
  392. return 0;
  393. }
  394. s32 CALLBACK CDVDgetDiskType()
  395. {
  396. return curDiskType;
  397. }
  398. s32 CALLBACK CDVDgetTrayStatus()
  399. {
  400. return curTrayStatus;
  401. }
  402. s32 CALLBACK CDVDctrlTrayOpen()
  403. {
  404. curTrayStatus=CDVD_TRAY_OPEN;
  405. return 0;
  406. }
  407. s32 CALLBACK CDVDctrlTrayClose()
  408. {
  409. curTrayStatus=CDVD_TRAY_CLOSE;
  410. return 0;
  411. }
  412. void CALLBACK CDVDnewDiskCB(void (*callback)())
  413. {
  414. newDiscCB=callback;
  415. }
  416. void configure();
  417. void CALLBACK CDVDconfigure()
  418. {
  419. configure();
  420. }
  421. void CALLBACK CDVDabout() {
  422. SysMessage("%s %d.%d", LibName, revision, build);
  423. }
  424. s32 CALLBACK CDVDtest() {
  425. return 0;
  426. }