REDBOOK.CPP 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. /*
  2. ** Command & Conquer Red Alert(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /***************************************************************************
  19. ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
  20. ***************************************************************************
  21. * *
  22. * Project Name : WWLIB *
  23. * *
  24. * File Name : REDBOOK.CPP *
  25. * *
  26. * Programmer : STEVE WETHERILL (FROM SCOTT BOWEN CODE) *
  27. * *
  28. * Start Date : 5/13/94 *
  29. * *
  30. * Last Update : June 4, 1994 [SW] *
  31. * *
  32. *-------------------------------------------------------------------------*
  33. *-------------------------------------------------------------------------*
  34. * Functions: *
  35. * RedBookClass::~RedBookClass(VOID) *
  36. * RedBookClass::RedToHS(ULONG i) *
  37. * RedBookClass::MSFtoRed(UBYTE m, UBYTE s, UBYTE f) *
  38. * RedBookClass::FullCDVolume(UBYTE chan) *
  39. * RedBookClass::PlayTrack(UWORD track) *
  40. * RedBookClass::Play_CD_MSL(UWORD min_sec, UWORD len) *
  41. * RedBookClass::PlayMSF(UBYTE startM, UBYTE startS, UBYTE startF, *
  42. * UBYTE endM, UBYTE endS, UBYTE endF, UBYTE chan) *
  43. * RedBookClass::CheckCDMusic(VOID) *
  44. * RedBookClass::StopCDMusic(VOID) *
  45. *= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
  46. #include <stddef.h>
  47. #include <stdio.h>
  48. #include <stdlib.h>
  49. #include <string.h>
  50. #include <dos.h>
  51. #include "wwstd.h"
  52. #include "playcd.h"
  53. #include "wwmem.h"
  54. /***************************************************************************
  55. * RedBookClass -- default constructor *
  56. * *
  57. * *
  58. * *
  59. * INPUT: *
  60. * none *
  61. * OUTPUT: *
  62. * none *
  63. * WARNINGS: *
  64. * calls GetCDDrive() *
  65. * HISTORY: *
  66. * 05/25/1994 SW : Created. *
  67. *=========================================================================*/
  68. RedBookClass::RedBookClass(VOID)
  69. : GetCDClass() // call the base constructor
  70. {
  71. SEGSEL tmpadr ;
  72. tmpadr = cdDrive_addrp;
  73. memset ( this , 0 , sizeof ( RedBookClass ) ) ;
  74. cdDrive_addrp = tmpadr ;
  75. Stop.Length = 13;
  76. Stop.Command = 133;
  77. Tinfo.Length = 26;
  78. Tinfo.Command = 3;
  79. Tinfo.CntTrns = 7;
  80. Tinfo.TrInfo = 11;
  81. Play.Length = 22;
  82. Play.Command = 132;
  83. Play.AddrMd = 1;
  84. Volm.Length = 26;
  85. Volm.Command = 12;
  86. Volm.CntTrns = 9;
  87. Volm.TrInfo = 3;
  88. Volm.In1 = 1;
  89. Volm.In2 = 2;
  90. Volm.In3 = 3;
  91. Stat.Length = 26;
  92. Stat.Command = 3;
  93. Stat.CntTrns = 11;
  94. Stat.StatInfo = 15;
  95. if (DPMI_real_alloc(sizeof(TinfoType)/16+1, &Tinfo_addrp, &largestp))
  96. exit(1);
  97. if (DPMI_real_alloc(sizeof(StatType)/16+1, &Stat_addrp, &largestp))
  98. exit(1);
  99. if (DPMI_real_alloc(sizeof(VolmType)/16+1, &Volm_addrp, &largestp))
  100. exit(1);
  101. if (DPMI_real_alloc(sizeof(PlayType)/16+1, &Play_addrp, &largestp))
  102. exit(1);
  103. if (DPMI_real_alloc(sizeof(StopType)/16+1, &Stop_addrp, &largestp))
  104. exit(1);
  105. GetCDDrive();
  106. }
  107. /***************************************************************************
  108. * REDBOOKCLASS -- destructor *
  109. * *
  110. * *
  111. * *
  112. * INPUT: *
  113. * none *
  114. * OUTPUT: *
  115. * none *
  116. * WARNINGS: *
  117. * *
  118. * HISTORY: *
  119. * 05/26/1994 SW : Created. *
  120. *=========================================================================*/
  121. RedBookClass::~RedBookClass(VOID)
  122. {
  123. if(Tinfo_addrp.seg)
  124. DPMI_real_free(Tinfo_addrp); // free up those conventional buffers
  125. if(Stat_addrp.seg)
  126. DPMI_real_free(Stat_addrp);
  127. if(Volm_addrp.seg)
  128. DPMI_real_free(Volm_addrp);
  129. if(Play_addrp.seg)
  130. DPMI_real_free(Play_addrp);
  131. if(Stop_addrp.seg)
  132. DPMI_real_free(Stop_addrp);
  133. }
  134. /***************************************************************************
  135. * REDTOHS -- RedBook to High-Sierra conversion *
  136. * *
  137. * *
  138. * *
  139. * INPUT: *
  140. * ULONG *
  141. * OUTPUT: *
  142. * ULONG *
  143. * WARNINGS: *
  144. * *
  145. * HISTORY: *
  146. * 05/26/1994 SW : Created. *
  147. *=========================================================================*/
  148. ULONG RedBookClass::RedToHS(ULONG i)
  149. {
  150. return( ((i>>16) & 0xFF) * 60 * 75) + ( ((i>>8) & 0xFF) * 75) + (i & 0xFF);
  151. }
  152. /***************************************************************************
  153. * MSFTORED -- Minute, Second, Frame to RedBook conversion *
  154. * *
  155. * *
  156. * *
  157. * INPUT: *
  158. * UBYTE minute *
  159. * UBYTE second *
  160. * UBYTE frame *
  161. * OUTPUT: *
  162. * ULONG RedBook *
  163. * WARNINGS: *
  164. * *
  165. * HISTORY: *
  166. * 05/26/1994 SW : Created. *
  167. *=========================================================================*/
  168. ULONG RedBookClass::MSFtoRed(UBYTE m, UBYTE s, UBYTE f)
  169. {
  170. return( ((ULONG)m << 16) + ((ULONG)s << 8) + (ULONG)f );
  171. }
  172. /***************************************************************************
  173. * FULLCDVOLUME -- set full volume *
  174. * *
  175. * *
  176. * *
  177. * INPUT: *
  178. * UBYTE channel *
  179. * *
  180. * CHLEFT *
  181. * CHRIGHT *
  182. * CHBOTH *
  183. * *
  184. * OUTPUT: *
  185. * none *
  186. * WARNINGS: *
  187. * *
  188. * HISTORY: *
  189. * 05/26/1994 SW : Created. *
  190. *=========================================================================*/
  191. VOID RedBookClass::FullCDVolume(UBYTE chan)
  192. {
  193. Volm.Vol0 = Volm.Vol1 = Volm.Vol2 = Volm.Vol3 = 255;
  194. Volm.TrnsAdOff = offsetof (VolmType, TrInfo);
  195. Volm.TrnsAdSeg = Volm_addrp.seg;
  196. if(chan == CHLEFT)
  197. {
  198. // Volm.In0 = 0;
  199. // Volm.In1 = 3;
  200. // Volm.In2 = 3;
  201. // Volm.In3 = 3;
  202. Volm.Vol1 = 0;
  203. }
  204. else if(chan == CHRIGHT)
  205. {
  206. // Volm.In0 = 3;
  207. // Volm.In1 = 1;
  208. // Volm.In2 = 3;
  209. // Volm.In3 = 3;
  210. Volm.Vol0 = 0;
  211. }
  212. else /* both channels */
  213. {
  214. Volm.In0 = 0;
  215. Volm.In1 = 1;
  216. Volm.In2 = 2;
  217. Volm.In3 = 3;
  218. }
  219. // WriteRealMem(REALPTR(Volm_addrp) << 16, &Volm, sizeof(VolmType));
  220. Mem_Copy ( &Volm , (void *) ( Volm_addrp.seg << 4 ) , sizeof(VolmType));
  221. regs.x.eax = 0x1510;
  222. regs.x.ecx = cdDrive[0];
  223. regs.x.ebx = 0x0000;
  224. sregs.es = Volm_addrp.seg;
  225. DPMI_real_intr(0x2F, &regs, & sregs);
  226. // ReadRealMem(&Volm, REALPTR(Volm_addrp) << 16, sizeof(VolmType));
  227. Mem_Copy ( (void *) ( Volm_addrp . seg << 4 ), &Volm ,sizeof(VolmType));
  228. }
  229. /***************************************************************************
  230. * PLAYTRACK -- play a track *
  231. * *
  232. * *
  233. * *
  234. * INPUT: *
  235. * UWORD track *
  236. * OUTPUT: *
  237. * none *
  238. * WARNINGS: *
  239. * *
  240. * HISTORY: *
  241. * 05/26/1994 SW : Created. *
  242. *=========================================================================*/
  243. VOID RedBookClass::PlayTrack(UWORD track)
  244. {
  245. StopCDMusic();
  246. Tinfo.Track = track;
  247. Tinfo.TrnsAdOff = offsetof (TinfoType, TrInfo);
  248. Tinfo.TrnsAdSeg = Tinfo_addrp.seg;
  249. // WriteRealMem(REALPTR(Tinfo_addrp) << 16, &Tinfo, sizeof(TinfoType));
  250. Mem_Copy ( &Tinfo , (void *) ( Tinfo_addrp.seg << 4 ) , sizeof(TinfoType));
  251. regs.x.eax = 0x1510;
  252. regs.x.ecx = cdDrive[0];
  253. regs.x.ebx = 0x0000;
  254. sregs.es = Tinfo_addrp.seg;
  255. DPMI_real_intr(0x2F, &regs, &sregs); // gets start time of track in Tinfo.Start
  256. // ReadRealMem(&Tinfo, REALPTR(Tinfo_addrp) << 16, sizeof(TinfoType));
  257. Mem_Copy ( (void *) ( Tinfo_addrp.seg << 4 ) , &Tinfo, sizeof(TinfoType));
  258. Play.Start = Tinfo.Start;
  259. Tinfo.Track++;
  260. Tinfo.TrnsAdOff = offsetof (TinfoType, TrInfo);
  261. Tinfo.TrnsAdSeg = Tinfo_addrp.seg;
  262. // WriteRealMem(REALPTR(Tinfo_addrp) << 16, &Tinfo, sizeof(TinfoType));
  263. Mem_Copy ( &Tinfo , (void *) ( Tinfo_addrp.seg << 4 ) , sizeof(TinfoType));
  264. regs.x.eax = 0x1510;
  265. regs.x.ecx = cdDrive[0];
  266. regs.x.ebx = 0x0000;
  267. sregs.es = Tinfo_addrp.seg;
  268. DPMI_real_intr(0x2F, &regs , &sregs); // gets start time of following track in Tinfo.Start
  269. // ReadRealMem(&Tinfo, REALPTR(Tinfo_addrp) << 16, sizeof(TinfoType));
  270. Mem_Copy ( (void *) ( Tinfo_addrp.seg << 4 ) , &Tinfo, sizeof(TinfoType));
  271. Play.CntSect = RedToHS(Tinfo.Start) - RedToHS(Play.Start) - 1;
  272. // WriteRealMem(REALPTR(Play_addrp) << 16, &Play, sizeof(PlayType));
  273. Mem_Copy ( &Play , (void *) ( Play_addrp.seg << 4 ) , sizeof(PlayType));
  274. regs.x.eax = 0x1510;
  275. regs.x.ecx = cdDrive[0];
  276. regs.x.ebx = 0x0000;
  277. sregs.es = Play_addrp.seg;
  278. DPMI_real_intr(0x2F, &regs, &sregs);
  279. // ReadRealMem(&Play, REALPTR(Play_addrp) << 16, sizeof(PlayType));
  280. Mem_Copy ( (void *) ( Play_addrp.seg << 4 ) , &Play, sizeof(PlayType));
  281. FullCDVolume(CHBOTH);
  282. }
  283. /***************************************************************************
  284. * PLAY_CD_MSL -- play cd from start min_sec for len *
  285. * *
  286. * *
  287. * *
  288. * INPUT: *
  289. * UWORD min_sec *
  290. * UWORD Len *
  291. * OUTPUT: *
  292. * none *
  293. * WARNINGS: *
  294. * *
  295. * HISTORY: *
  296. * 05/26/1994 SW : Created. *
  297. *=========================================================================*/
  298. VOID RedBookClass::Play_CD_MSL(UWORD min_sec, UWORD len)
  299. {
  300. UWORD startM, startS, startF;
  301. UWORD endM, endS, endF;
  302. if (!len)
  303. return;
  304. endM = startM = (min_sec >> 8) + AUDIO_START_MIN;
  305. endS = startS = (min_sec & 0xFF) + AUDIO_START_SEC;
  306. startF = endF = 0;
  307. while (len > 59) {
  308. endM++;
  309. len -= 60;
  310. }
  311. endS += len;
  312. if (endS > 59) {
  313. endM++;
  314. endS -= 60;
  315. }
  316. PlayMSF((UBYTE) startM, (UBYTE)startS, (UBYTE)startF, (UBYTE)endM, (UBYTE)endS, (UBYTE)endF, 2 /* chan */);
  317. }
  318. /***************************************************************************
  319. * PlayMSF -- Play Minute, Second, Frame to Minute, Second, Frame *
  320. * *
  321. * *
  322. * *
  323. * INPUT: *
  324. * UBYTE startM *
  325. * UBYTE startS *
  326. * UBYTE startF *
  327. * UBYTE endM *
  328. * UBYTE endS *
  329. * UBYTE endF *
  330. * UBYTE chan *
  331. * OUTPUT: *
  332. * none *
  333. * WARNINGS: *
  334. * *
  335. * HISTORY: *
  336. * 05/27/1994 SW : Created. *
  337. *=========================================================================*/
  338. VOID RedBookClass::PlayMSF(UBYTE startM, UBYTE startS, UBYTE startF, UBYTE endM, UBYTE endS, UBYTE endF, UBYTE chan)
  339. {
  340. Play.Start = MSFtoRed(startM, startS, startF);
  341. Play.CntSect = RedToHS(MSFtoRed(endM, endS, endF)) - RedToHS(Play.Start) - 1;
  342. // WriteRealMem(REALPTR(Play_addrp) << 16, &Play, sizeof(PlayType));
  343. Mem_Copy ( &Play , (void *) ( Play_addrp.seg << 4 ) , sizeof(PlayType));
  344. regs.x.eax = 0x1510;
  345. regs.x.ecx = cdDrive[0];
  346. regs.x.ebx = offsetof (PlayType, Length);
  347. sregs.es = Play_addrp.seg;
  348. DPMI_real_intr(0x2F, &regs, &sregs);
  349. // ReadRealMem(&Play, REALPTR(Play_addrp) << 16, sizeof(PlayType));
  350. Mem_Copy ( (void *) ( Play_addrp.seg << 4 ) , &Play, sizeof(PlayType));
  351. FullCDVolume(chan);
  352. }
  353. /***************************************************************************
  354. * CheckCDMusic -- Check for CD playing *
  355. * *
  356. * *
  357. * *
  358. * INPUT: *
  359. * UBYTE startM *
  360. * UBYTE startS *
  361. * UBYTE startF *
  362. * UBYTE endM *
  363. * UBYTE endS *
  364. * UBYTE endF *
  365. * UBYTE chan *
  366. * OUTPUT: *
  367. * UWORD TRUE if playing else FALSE *
  368. * WARNINGS: *
  369. * *
  370. * HISTORY: *
  371. * 05/27/1994 SW : Created. *
  372. *=========================================================================*/
  373. UWORD RedBookClass::CheckCDMusic(VOID)
  374. {
  375. Stat.TrnsAdOff = offsetof (StatType, StatInfo);
  376. Stat.TrnsAdSeg = Stat_addrp.seg;
  377. // WriteRealMem(REALPTR(Stat_addrp) << 16, &Stat, sizeof(StatType));
  378. Mem_Copy ( &Stat , (void *) ( Stat_addrp.seg << 4 ) , sizeof(StatType));
  379. regs.x.ecx = cdDrive[0];
  380. regs.x.ebx = offsetof (StatType, Length);
  381. regs.x.eax = 0x1510;
  382. sregs.es = Stat_addrp.seg;
  383. DPMI_real_intr(0x2F, &regs, &sregs);
  384. // ReadRealMem(&Stat, REALPTR(Stat_addrp) << 16, sizeof(StatType));
  385. Mem_Copy ( (void *) ( Stat_addrp.seg << 4 ) , &Stat, sizeof(StatType));
  386. return (Stat.Status&0x200);
  387. }
  388. /***************************************************************************
  389. * STOPCDMUSIC -- stop CD playing *
  390. * *
  391. * *
  392. * *
  393. * INPUT: *
  394. * none *
  395. * OUTPUT: *
  396. * none *
  397. * WARNINGS: *
  398. * *
  399. * HISTORY: *
  400. * 05/27/1994 SW : Created. *
  401. *=========================================================================*/
  402. VOID RedBookClass::StopCDMusic(VOID)
  403. {
  404. // WriteRealMem(REALPTR(Stop_addrp) << 16, &Stop, sizeof(StopType));
  405. Mem_Copy ( &Stop , (void *) ( Stop_addrp.seg << 4 ) , sizeof(StopType));
  406. regs.x.eax = 0x1510;
  407. regs.x.ecx = cdDrive[0];
  408. regs.x.ebx = offsetof (StopType, Length);
  409. sregs.es = Stop_addrp.seg;
  410. DPMI_real_intr(0x2F, &regs, &sregs);
  411. // ReadRealMem(&Stop, REALPTR(Stop_addrp) << 16, sizeof(StopType));
  412. Mem_Copy ( (void *) ( Stop_addrp.seg << 4 ) , &Stop, sizeof(StopType));
  413. }