Guest User

save_states_4176_diff.patch

a guest
Apr 24th, 2020
190
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 433.83 KB | None | 0 0
  1. Index: include/cpu.h
  2. ===================================================================
  3. --- include/cpu.h (revision 4176)
  4. +++ include/cpu.h (working copy)
  5. @@ -20,6 +20,8 @@
  6. #ifndef DOSBOX_CPU_H
  7. #define DOSBOX_CPU_H
  8.  
  9. +#include <sstream>
  10. +
  11. #ifndef DOSBOX_DOSBOX_H
  12. #include "dosbox.h"
  13. #endif
  14. @@ -377,6 +379,10 @@
  15. desc.Load(table_base+(selector));
  16. return true;
  17. }
  18. +
  19. + virtual void SaveState( std::ostream& stream );
  20. + virtual void LoadState( std::istream& stream );
  21. +
  22. protected:
  23. PhysPt table_base;
  24. Bitu table_limit;
  25. @@ -427,6 +433,10 @@
  26. ldt_value=value;
  27. return true;
  28. }
  29. +
  30. + virtual void SaveState( std::ostream& stream );
  31. + virtual void LoadState( std::istream& stream );
  32. +
  33. private:
  34. PhysPt ldt_base;
  35. Bitu ldt_limit;
  36. Index: include/crypt.h
  37. ===================================================================
  38. --- include/crypt.h (nonexistent)
  39. +++ include/crypt.h (working copy)
  40. @@ -0,0 +1,131 @@
  41. +/* crypt.h -- base code for crypt/uncrypt ZIPfile
  42. +
  43. +
  44. + Version 1.01e, February 12th, 2005
  45. +
  46. + Copyright (C) 1998-2005 Gilles Vollant
  47. +
  48. + This code is a modified version of crypting code in Infozip distribution
  49. +
  50. + The encryption/decryption parts of this source code (as opposed to the
  51. + non-echoing password parts) were originally written in Europe. The
  52. + whole source package can be freely distributed, including from the USA.
  53. + (Prior to January 2000, re-export from the US was a violation of US law.)
  54. +
  55. + This encryption code is a direct transcription of the algorithm from
  56. + Roger Schlafly, described by Phil Katz in the file appnote.txt. This
  57. + file (appnote.txt) is distributed with the PKZIP program (even in the
  58. + version without encryption capabilities).
  59. +
  60. + If you don't need crypting in your application, just define symbols
  61. + NOCRYPT and NOUNCRYPT.
  62. +
  63. + This code support the "Traditional PKWARE Encryption".
  64. +
  65. + The new AES encryption added on Zip format by Winzip (see the page
  66. + http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong
  67. + Encryption is not supported.
  68. +*/
  69. +
  70. +#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
  71. +
  72. +/***********************************************************************
  73. + * Return the next byte in the pseudo-random sequence
  74. + */
  75. +static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab)
  76. +{
  77. + unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
  78. + * unpredictable manner on 16-bit systems; not a problem
  79. + * with any known compiler so far, though */
  80. +
  81. + temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;
  82. + return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
  83. +}
  84. +
  85. +/***********************************************************************
  86. + * Update the encryption keys with the next byte of plain text
  87. + */
  88. +static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c)
  89. +{
  90. + (*(pkeys+0)) = CRC32((*(pkeys+0)), c);
  91. + (*(pkeys+1)) += (*(pkeys+0)) & 0xff;
  92. + (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
  93. + {
  94. + register int keyshift = (int)((*(pkeys+1)) >> 24);
  95. + (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);
  96. + }
  97. + return c;
  98. +}
  99. +
  100. +
  101. +/***********************************************************************
  102. + * Initialize the encryption keys and the random header according to
  103. + * the given password.
  104. + */
  105. +static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab)
  106. +{
  107. + *(pkeys+0) = 305419896L;
  108. + *(pkeys+1) = 591751049L;
  109. + *(pkeys+2) = 878082192L;
  110. + while (*passwd != '\0') {
  111. + update_keys(pkeys,pcrc_32_tab,(int)*passwd);
  112. + passwd++;
  113. + }
  114. +}
  115. +
  116. +#define zdecode(pkeys,pcrc_32_tab,c) \
  117. + (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))
  118. +
  119. +#define zencode(pkeys,pcrc_32_tab,c,t) \
  120. + (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c))
  121. +
  122. +#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED
  123. +
  124. +#define RAND_HEAD_LEN 12
  125. + /* "last resort" source for second part of crypt seed pattern */
  126. +# ifndef ZCR_SEED2
  127. +# define ZCR_SEED2 3141592654UL /* use PI as default pattern */
  128. +# endif
  129. +
  130. +static int crypthead(const char* passwd, /* password string */
  131. + unsigned char* buf, /* where to write header */
  132. + int bufSize,
  133. + unsigned long* pkeys,
  134. + const unsigned long* pcrc_32_tab,
  135. + unsigned long crcForCrypting)
  136. +{
  137. + int n; /* index in random header */
  138. + int t; /* temporary */
  139. + int c; /* random byte */
  140. + unsigned char header[RAND_HEAD_LEN-2]; /* random header */
  141. + static unsigned calls = 0; /* ensure different random header each time */
  142. +
  143. + if (bufSize<RAND_HEAD_LEN)
  144. + return 0;
  145. +
  146. + /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
  147. + * output of rand() to get less predictability, since rand() is
  148. + * often poorly implemented.
  149. + */
  150. + if (++calls == 1)
  151. + {
  152. + srand((unsigned)(time(NULL) ^ ZCR_SEED2));
  153. + }
  154. + init_keys(passwd, pkeys, pcrc_32_tab);
  155. + for (n = 0; n < RAND_HEAD_LEN-2; n++)
  156. + {
  157. + c = (rand() >> 7) & 0xff;
  158. + header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);
  159. + }
  160. + /* Encrypt random header (last two bytes is high word of crc) */
  161. + init_keys(passwd, pkeys, pcrc_32_tab);
  162. + for (n = 0; n < RAND_HEAD_LEN-2; n++)
  163. + {
  164. + buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);
  165. + }
  166. + buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);
  167. + buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);
  168. + return n;
  169. +}
  170. +
  171. +#endif
  172. Index: include/dma.h
  173. ===================================================================
  174. --- include/dma.h (revision 4176)
  175. +++ include/dma.h (working copy)
  176. @@ -20,6 +20,8 @@
  177. #ifndef DOSBOX_DMA_H
  178. #define DOSBOX_DMA_H
  179.  
  180. +#include <sstream>
  181. +
  182. enum DMAEvent {
  183. DMA_REACHED_TC,
  184. DMA_MASKED,
  185. @@ -78,6 +80,10 @@
  186. }
  187. Bitu Read(Bitu size, Bit8u * buffer);
  188. Bitu Write(Bitu size, Bit8u * buffer);
  189. +
  190. + void SaveState( std::ostream& stream );
  191. + void LoadState( std::istream& stream );
  192. +
  193. };
  194.  
  195. class DmaController {
  196. @@ -106,6 +112,10 @@
  197. }
  198. void WriteControllerReg(Bitu reg,Bitu val,Bitu len);
  199. Bitu ReadControllerReg(Bitu reg,Bitu len);
  200. +
  201. + void SaveState( std::ostream& stream );
  202. + void LoadState( std::istream& stream );
  203. +
  204. };
  205.  
  206. DmaChannel * GetDMAChannel(Bit8u chan);
  207. Index: include/dos_system.h
  208. ===================================================================
  209. --- include/dos_system.h (revision 4176)
  210. +++ include/dos_system.h (working copy)
  211. @@ -78,8 +78,15 @@
  212. virtual void AddRef() { refCtr++; };
  213. virtual Bits RemoveRef() { return --refCtr; };
  214. virtual bool UpdateDateTimeFromHost() { return true; }
  215. +
  216. + virtual Bit32u GetSeekPos() { return 0xffffffff; }
  217. +
  218. void SetDrive(Bit8u drv) { hdrive=drv;}
  219. Bit8u GetDrive(void) { return hdrive;}
  220. +
  221. + virtual void SaveState( std::ostream& stream );
  222. + virtual void LoadState( std::istream& stream, bool pop );
  223. +
  224. Bit32u flags;
  225. Bit16u time;
  226. Bit16u date;
  227. @@ -119,6 +126,7 @@
  228.  
  229. class localFile : public DOS_File {
  230. public:
  231. + localFile();
  232. localFile(const char* name, FILE * handle);
  233. bool Read(Bit8u * data,Bit16u * size);
  234. bool Write(Bit8u * data,Bit16u * size);
  235. @@ -128,6 +136,9 @@
  236. bool UpdateDateTimeFromHost(void);
  237. void FlagReadOnlyMedium(void);
  238. void Flush(void);
  239. +
  240. + Bit32u GetSeekPos(void);
  241. +
  242. private:
  243. FILE * fhandle;
  244. bool read_only_medium;
  245. @@ -264,6 +275,10 @@
  246.  
  247. // disk cycling functionality (request resources)
  248. virtual void Activate(void) {};
  249. +
  250. + virtual void SaveState( std::ostream& stream );
  251. + virtual void LoadState( std::istream& stream );
  252. +
  253. };
  254.  
  255. enum { OPEN_READ=0, OPEN_WRITE=1, OPEN_READWRITE=2, OPEN_READ_NO_MOD=4, DOS_NOT_INHERIT=128};
  256. Index: include/ioapi.h
  257. ===================================================================
  258. --- include/ioapi.h (nonexistent)
  259. +++ include/ioapi.h (working copy)
  260. @@ -0,0 +1,200 @@
  261. +/* ioapi.h -- IO base function header for compress/uncompress .zip
  262. + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
  263. +
  264. + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
  265. +
  266. + Modifications for Zip64 support
  267. + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
  268. +
  269. + For more info read MiniZip_info.txt
  270. +
  271. + Changes
  272. +
  273. + Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this)
  274. + Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux.
  275. + More if/def section may be needed to support other platforms
  276. + Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows.
  277. + (but you should use iowin32.c for windows instead)
  278. +
  279. +*/
  280. +
  281. +#ifndef _ZLIBIOAPI64_H
  282. +#define _ZLIBIOAPI64_H
  283. +
  284. +#if (!defined(_WIN32)) && (!defined(WIN32))
  285. +
  286. + // Linux needs this to support file operation on files larger then 4+GB
  287. + // But might need better if/def to select just the platforms that needs them.
  288. +
  289. + #ifndef __USE_FILE_OFFSET64
  290. + #define __USE_FILE_OFFSET64
  291. + #endif
  292. + #ifndef __USE_LARGEFILE64
  293. + #define __USE_LARGEFILE64
  294. + #endif
  295. + #ifndef _LARGEFILE64_SOURCE
  296. + #define _LARGEFILE64_SOURCE
  297. + #endif
  298. + #ifndef _FILE_OFFSET_BIT
  299. + #define _FILE_OFFSET_BIT 64
  300. + #endif
  301. +#endif
  302. +
  303. +#include <stdio.h>
  304. +#include <stdlib.h>
  305. +#include "zlib.h"
  306. +
  307. +#if defined(__APPLE__) || defined(USE_FILE32API)
  308. +#define fopen64 fopen
  309. +#define ftello64 ftell
  310. +#define fseeko64 fseek
  311. +#else
  312. +#ifdef _MSC_VER
  313. + #define fopen64 fopen
  314. + #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC)))
  315. + #define ftello64 _ftelli64
  316. + #define fseeko64 _fseeki64
  317. + #else // old MSC
  318. + #define ftello64 ftell
  319. + #define fseeko64 fseek
  320. + #endif
  321. +#endif
  322. +#endif
  323. +
  324. +/*
  325. +#ifndef ZPOS64_T
  326. + #ifdef _WIN32
  327. + #define ZPOS64_T fpos_t
  328. + #else
  329. + #include <stdint.h>
  330. + #define ZPOS64_T uint64_t
  331. + #endif
  332. +#endif
  333. +*/
  334. +
  335. +#ifdef HAVE_MINIZIP64_CONF_H
  336. +#include "mz64conf.h"
  337. +#endif
  338. +
  339. +/* a type choosen by DEFINE */
  340. +#ifdef HAVE_64BIT_INT_CUSTOM
  341. +typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T;
  342. +#else
  343. +#ifdef HAS_STDINT_H
  344. +#include "stdint.h"
  345. +typedef uint64_t ZPOS64_T;
  346. +#else
  347. +
  348. +
  349. +#if defined(_MSC_VER) || defined(__BORLANDC__)
  350. +typedef unsigned __int64 ZPOS64_T;
  351. +#else
  352. +typedef unsigned long long int ZPOS64_T;
  353. +#endif
  354. +#endif
  355. +#endif
  356. +
  357. +
  358. +
  359. +#ifdef __cplusplus
  360. +extern "C" {
  361. +#endif
  362. +
  363. +
  364. +#define ZLIB_FILEFUNC_SEEK_CUR (1)
  365. +#define ZLIB_FILEFUNC_SEEK_END (2)
  366. +#define ZLIB_FILEFUNC_SEEK_SET (0)
  367. +
  368. +#define ZLIB_FILEFUNC_MODE_READ (1)
  369. +#define ZLIB_FILEFUNC_MODE_WRITE (2)
  370. +#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
  371. +
  372. +#define ZLIB_FILEFUNC_MODE_EXISTING (4)
  373. +#define ZLIB_FILEFUNC_MODE_CREATE (8)
  374. +
  375. +
  376. +#ifndef ZCALLBACK
  377. + #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)
  378. + #define ZCALLBACK CALLBACK
  379. + #else
  380. + #define ZCALLBACK
  381. + #endif
  382. +#endif
  383. +
  384. +
  385. +
  386. +
  387. +typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode));
  388. +typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size));
  389. +typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
  390. +typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream));
  391. +typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));
  392. +
  393. +typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream));
  394. +typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin));
  395. +
  396. +
  397. +/* here is the "old" 32 bits structure structure */
  398. +typedef struct zlib_filefunc_def_s
  399. +{
  400. + open_file_func zopen_file;
  401. + read_file_func zread_file;
  402. + write_file_func zwrite_file;
  403. + tell_file_func ztell_file;
  404. + seek_file_func zseek_file;
  405. + close_file_func zclose_file;
  406. + testerror_file_func zerror_file;
  407. + voidpf opaque;
  408. +} zlib_filefunc_def;
  409. +
  410. +typedef ZPOS64_T (ZCALLBACK *tell64_file_func) OF((voidpf opaque, voidpf stream));
  411. +typedef long (ZCALLBACK *seek64_file_func) OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
  412. +typedef voidpf (ZCALLBACK *open64_file_func) OF((voidpf opaque, const void* filename, int mode));
  413. +
  414. +typedef struct zlib_filefunc64_def_s
  415. +{
  416. + open64_file_func zopen64_file;
  417. + read_file_func zread_file;
  418. + write_file_func zwrite_file;
  419. + tell64_file_func ztell64_file;
  420. + seek64_file_func zseek64_file;
  421. + close_file_func zclose_file;
  422. + testerror_file_func zerror_file;
  423. + voidpf opaque;
  424. +} zlib_filefunc64_def;
  425. +
  426. +void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def));
  427. +void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
  428. +
  429. +/* now internal definition, only for zip.c and unzip.h */
  430. +typedef struct zlib_filefunc64_32_def_s
  431. +{
  432. + zlib_filefunc64_def zfile_func64;
  433. + open_file_func zopen32_file;
  434. + tell_file_func ztell32_file;
  435. + seek_file_func zseek32_file;
  436. +} zlib_filefunc64_32_def;
  437. +
  438. +
  439. +#define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size))
  440. +#define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size))
  441. +//#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream))
  442. +//#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode))
  443. +#define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream))
  444. +#define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream))
  445. +
  446. +voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode));
  447. +long call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin));
  448. +ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream));
  449. +
  450. +void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32);
  451. +
  452. +#define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode)))
  453. +#define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream)))
  454. +#define ZSEEK64(filefunc,filestream,pos,mode) (call_zseek64((&(filefunc)),(filestream),(pos),(mode)))
  455. +
  456. +#ifdef __cplusplus
  457. +}
  458. +#endif
  459. +
  460. +#endif
  461. Index: include/mixer.h
  462. ===================================================================
  463. --- include/mixer.h (revision 4176)
  464. +++ include/mixer.h (working copy)
  465. @@ -20,6 +20,8 @@
  466. #ifndef DOSBOX_MIXER_H
  467. #define DOSBOX_MIXER_H
  468.  
  469. +#include <sstream>
  470. +
  471. #ifndef DOSBOX_DOSBOX_H
  472. #include "dosbox.h"
  473. #endif
  474. @@ -77,6 +79,10 @@
  475.  
  476. void FillUp(void);
  477. void Enable(bool _yesno);
  478. +
  479. + void SaveState( std::ostream& stream );
  480. + void LoadState( std::istream& stream );
  481. +
  482. MIXER_Handler handler;
  483. float volmain[2];
  484. float scale;
  485. Index: include/unzip.h
  486. ===================================================================
  487. --- include/unzip.h (nonexistent)
  488. +++ include/unzip.h (working copy)
  489. @@ -0,0 +1,437 @@
  490. +/* unzip.h -- IO for uncompress .zip files using zlib
  491. + Version 1.1, February 14h, 2010
  492. + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
  493. +
  494. + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
  495. +
  496. + Modifications of Unzip for Zip64
  497. + Copyright (C) 2007-2008 Even Rouault
  498. +
  499. + Modifications for Zip64 support on both zip and unzip
  500. + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
  501. +
  502. + For more info read MiniZip_info.txt
  503. +
  504. + ---------------------------------------------------------------------------------
  505. +
  506. + Condition of use and distribution are the same than zlib :
  507. +
  508. + This software is provided 'as-is', without any express or implied
  509. + warranty. In no event will the authors be held liable for any damages
  510. + arising from the use of this software.
  511. +
  512. + Permission is granted to anyone to use this software for any purpose,
  513. + including commercial applications, and to alter it and redistribute it
  514. + freely, subject to the following restrictions:
  515. +
  516. + 1. The origin of this software must not be misrepresented; you must not
  517. + claim that you wrote the original software. If you use this software
  518. + in a product, an acknowledgment in the product documentation would be
  519. + appreciated but is not required.
  520. + 2. Altered source versions must be plainly marked as such, and must not be
  521. + misrepresented as being the original software.
  522. + 3. This notice may not be removed or altered from any source distribution.
  523. +
  524. + ---------------------------------------------------------------------------------
  525. +
  526. + Changes
  527. +
  528. + See header of unzip64.c
  529. +
  530. +*/
  531. +
  532. +#ifndef _unz64_H
  533. +#define _unz64_H
  534. +
  535. +#ifdef __cplusplus
  536. +extern "C" {
  537. +#endif
  538. +
  539. +#ifndef _ZLIB_H
  540. +#include "zlib.h"
  541. +#endif
  542. +
  543. +#ifndef _ZLIBIOAPI_H
  544. +#include "ioapi.h"
  545. +#endif
  546. +
  547. +#ifdef HAVE_BZIP2
  548. +#include "bzlib.h"
  549. +#endif
  550. +
  551. +#define Z_BZIP2ED 12
  552. +
  553. +#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
  554. +/* like the STRICT of WIN32, we define a pointer that cannot be converted
  555. + from (void*) without cast */
  556. +typedef struct TagunzFile__ { int unused; } unzFile__;
  557. +typedef unzFile__ *unzFile;
  558. +#else
  559. +typedef voidp unzFile;
  560. +#endif
  561. +
  562. +
  563. +#define UNZ_OK (0)
  564. +#define UNZ_END_OF_LIST_OF_FILE (-100)
  565. +#define UNZ_ERRNO (Z_ERRNO)
  566. +#define UNZ_EOF (0)
  567. +#define UNZ_PARAMERROR (-102)
  568. +#define UNZ_BADZIPFILE (-103)
  569. +#define UNZ_INTERNALERROR (-104)
  570. +#define UNZ_CRCERROR (-105)
  571. +
  572. +/* tm_unz contain date/time info */
  573. +typedef struct tm_unz_s
  574. +{
  575. + uInt tm_sec; /* seconds after the minute - [0,59] */
  576. + uInt tm_min; /* minutes after the hour - [0,59] */
  577. + uInt tm_hour; /* hours since midnight - [0,23] */
  578. + uInt tm_mday; /* day of the month - [1,31] */
  579. + uInt tm_mon; /* months since January - [0,11] */
  580. + uInt tm_year; /* years - [1980..2044] */
  581. +} tm_unz;
  582. +
  583. +/* unz_global_info structure contain global data about the ZIPfile
  584. + These data comes from the end of central dir */
  585. +typedef struct unz_global_info64_s
  586. +{
  587. + ZPOS64_T number_entry; /* total number of entries in
  588. + the central dir on this disk */
  589. + uLong size_comment; /* size of the global comment of the zipfile */
  590. +} unz_global_info64;
  591. +
  592. +typedef struct unz_global_info_s
  593. +{
  594. + uLong number_entry; /* total number of entries in
  595. + the central dir on this disk */
  596. + uLong size_comment; /* size of the global comment of the zipfile */
  597. +} unz_global_info;
  598. +
  599. +/* unz_file_info contain information about a file in the zipfile */
  600. +typedef struct unz_file_info64_s
  601. +{
  602. + uLong version; /* version made by 2 bytes */
  603. + uLong version_needed; /* version needed to extract 2 bytes */
  604. + uLong flag; /* general purpose bit flag 2 bytes */
  605. + uLong compression_method; /* compression method 2 bytes */
  606. + uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
  607. + uLong crc; /* crc-32 4 bytes */
  608. + ZPOS64_T compressed_size; /* compressed size 8 bytes */
  609. + ZPOS64_T uncompressed_size; /* uncompressed size 8 bytes */
  610. + uLong size_filename; /* filename length 2 bytes */
  611. + uLong size_file_extra; /* extra field length 2 bytes */
  612. + uLong size_file_comment; /* file comment length 2 bytes */
  613. +
  614. + uLong disk_num_start; /* disk number start 2 bytes */
  615. + uLong internal_fa; /* internal file attributes 2 bytes */
  616. + uLong external_fa; /* external file attributes 4 bytes */
  617. +
  618. + tm_unz tmu_date;
  619. +} unz_file_info64;
  620. +
  621. +typedef struct unz_file_info_s
  622. +{
  623. + uLong version; /* version made by 2 bytes */
  624. + uLong version_needed; /* version needed to extract 2 bytes */
  625. + uLong flag; /* general purpose bit flag 2 bytes */
  626. + uLong compression_method; /* compression method 2 bytes */
  627. + uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
  628. + uLong crc; /* crc-32 4 bytes */
  629. + uLong compressed_size; /* compressed size 4 bytes */
  630. + uLong uncompressed_size; /* uncompressed size 4 bytes */
  631. + uLong size_filename; /* filename length 2 bytes */
  632. + uLong size_file_extra; /* extra field length 2 bytes */
  633. + uLong size_file_comment; /* file comment length 2 bytes */
  634. +
  635. + uLong disk_num_start; /* disk number start 2 bytes */
  636. + uLong internal_fa; /* internal file attributes 2 bytes */
  637. + uLong external_fa; /* external file attributes 4 bytes */
  638. +
  639. + tm_unz tmu_date;
  640. +} unz_file_info;
  641. +
  642. +extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
  643. + const char* fileName2,
  644. + int iCaseSensitivity));
  645. +/*
  646. + Compare two filename (fileName1,fileName2).
  647. + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
  648. + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
  649. + or strcasecmp)
  650. + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
  651. + (like 1 on Unix, 2 on Windows)
  652. +*/
  653. +
  654. +
  655. +extern unzFile ZEXPORT unzOpen OF((const char *path));
  656. +extern unzFile ZEXPORT unzOpen64 OF((const void *path));
  657. +/*
  658. + Open a Zip file. path contain the full pathname (by example,
  659. + on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer
  660. + "zlib/zlib113.zip".
  661. + If the zipfile cannot be opened (file don't exist or in not valid), the
  662. + return value is NULL.
  663. + Else, the return value is a unzFile Handle, usable with other function
  664. + of this unzip package.
  665. + the "64" function take a const void* pointer, because the path is just the
  666. + value passed to the open64_file_func callback.
  667. + Under Windows, if UNICODE is defined, using fill_fopen64_filefunc, the path
  668. + is a pointer to a wide unicode string (LPCTSTR is LPCWSTR), so const char*
  669. + does not describe the reality
  670. +*/
  671. +
  672. +
  673. +extern unzFile ZEXPORT unzOpen2 OF((const char *path,
  674. + zlib_filefunc_def* pzlib_filefunc_def));
  675. +/*
  676. + Open a Zip file, like unzOpen, but provide a set of file low level API
  677. + for read/write the zip file (see ioapi.h)
  678. +*/
  679. +
  680. +extern unzFile ZEXPORT unzOpen2_64 OF((const void *path,
  681. + zlib_filefunc64_def* pzlib_filefunc_def));
  682. +/*
  683. + Open a Zip file, like unz64Open, but provide a set of file low level API
  684. + for read/write the zip file (see ioapi.h)
  685. +*/
  686. +
  687. +extern int ZEXPORT unzClose OF((unzFile file));
  688. +/*
  689. + Close a ZipFile opened with unzipOpen.
  690. + If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
  691. + these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
  692. + return UNZ_OK if there is no problem. */
  693. +
  694. +extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
  695. + unz_global_info *pglobal_info));
  696. +
  697. +extern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file,
  698. + unz_global_info64 *pglobal_info));
  699. +/*
  700. + Write info about the ZipFile in the *pglobal_info structure.
  701. + No preparation of the structure is needed
  702. + return UNZ_OK if there is no problem. */
  703. +
  704. +
  705. +extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
  706. + char *szComment,
  707. + uLong uSizeBuf));
  708. +/*
  709. + Get the global comment string of the ZipFile, in the szComment buffer.
  710. + uSizeBuf is the size of the szComment buffer.
  711. + return the number of byte copied or an error code <0
  712. +*/
  713. +
  714. +
  715. +/***************************************************************************/
  716. +/* Unzip package allow you browse the directory of the zipfile */
  717. +
  718. +extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
  719. +/*
  720. + Set the current file of the zipfile to the first file.
  721. + return UNZ_OK if there is no problem
  722. +*/
  723. +
  724. +extern int ZEXPORT unzGoToNextFile OF((unzFile file));
  725. +/*
  726. + Set the current file of the zipfile to the next file.
  727. + return UNZ_OK if there is no problem
  728. + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
  729. +*/
  730. +
  731. +extern int ZEXPORT unzLocateFile OF((unzFile file,
  732. + const char *szFileName,
  733. + int iCaseSensitivity));
  734. +/*
  735. + Try locate the file szFileName in the zipfile.
  736. + For the iCaseSensitivity signification, see unzStringFileNameCompare
  737. +
  738. + return value :
  739. + UNZ_OK if the file is found. It becomes the current file.
  740. + UNZ_END_OF_LIST_OF_FILE if the file is not found
  741. +*/
  742. +
  743. +
  744. +/* ****************************************** */
  745. +/* Ryan supplied functions */
  746. +/* unz_file_info contain information about a file in the zipfile */
  747. +typedef struct unz_file_pos_s
  748. +{
  749. + uLong pos_in_zip_directory; /* offset in zip file directory */
  750. + uLong num_of_file; /* # of file */
  751. +} unz_file_pos;
  752. +
  753. +extern int ZEXPORT unzGetFilePos(
  754. + unzFile file,
  755. + unz_file_pos* file_pos);
  756. +
  757. +extern int ZEXPORT unzGoToFilePos(
  758. + unzFile file,
  759. + unz_file_pos* file_pos);
  760. +
  761. +typedef struct unz64_file_pos_s
  762. +{
  763. + ZPOS64_T pos_in_zip_directory; /* offset in zip file directory */
  764. + ZPOS64_T num_of_file; /* # of file */
  765. +} unz64_file_pos;
  766. +
  767. +extern int ZEXPORT unzGetFilePos64(
  768. + unzFile file,
  769. + unz64_file_pos* file_pos);
  770. +
  771. +extern int ZEXPORT unzGoToFilePos64(
  772. + unzFile file,
  773. + const unz64_file_pos* file_pos);
  774. +
  775. +/* ****************************************** */
  776. +
  777. +extern int ZEXPORT unzGetCurrentFileInfo64 OF((unzFile file,
  778. + unz_file_info64 *pfile_info,
  779. + char *szFileName,
  780. + uLong fileNameBufferSize,
  781. + void *extraField,
  782. + uLong extraFieldBufferSize,
  783. + char *szComment,
  784. + uLong commentBufferSize));
  785. +
  786. +extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
  787. + unz_file_info *pfile_info,
  788. + char *szFileName,
  789. + uLong fileNameBufferSize,
  790. + void *extraField,
  791. + uLong extraFieldBufferSize,
  792. + char *szComment,
  793. + uLong commentBufferSize));
  794. +/*
  795. + Get Info about the current file
  796. + if pfile_info!=NULL, the *pfile_info structure will contain somes info about
  797. + the current file
  798. + if szFileName!=NULL, the filemane string will be copied in szFileName
  799. + (fileNameBufferSize is the size of the buffer)
  800. + if extraField!=NULL, the extra field information will be copied in extraField
  801. + (extraFieldBufferSize is the size of the buffer).
  802. + This is the Central-header version of the extra field
  803. + if szComment!=NULL, the comment string of the file will be copied in szComment
  804. + (commentBufferSize is the size of the buffer)
  805. +*/
  806. +
  807. +
  808. +/** Addition for GDAL : START */
  809. +
  810. +extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file));
  811. +
  812. +/** Addition for GDAL : END */
  813. +
  814. +
  815. +/***************************************************************************/
  816. +/* for reading the content of the current zipfile, you can open it, read data
  817. + from it, and close it (you can close it before reading all the file)
  818. + */
  819. +
  820. +extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
  821. +/*
  822. + Open for reading data the current file in the zipfile.
  823. + If there is no error, the return value is UNZ_OK.
  824. +*/
  825. +
  826. +extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file,
  827. + const char* password));
  828. +/*
  829. + Open for reading data the current file in the zipfile.
  830. + password is a crypting password
  831. + If there is no error, the return value is UNZ_OK.
  832. +*/
  833. +
  834. +extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file,
  835. + int* method,
  836. + int* level,
  837. + int raw));
  838. +/*
  839. + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
  840. + if raw==1
  841. + *method will receive method of compression, *level will receive level of
  842. + compression
  843. + note : you can set level parameter as NULL (if you did not want known level,
  844. + but you CANNOT set method parameter as NULL
  845. +*/
  846. +
  847. +extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file,
  848. + int* method,
  849. + int* level,
  850. + int raw,
  851. + const char* password));
  852. +/*
  853. + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
  854. + if raw==1
  855. + *method will receive method of compression, *level will receive level of
  856. + compression
  857. + note : you can set level parameter as NULL (if you did not want known level,
  858. + but you CANNOT set method parameter as NULL
  859. +*/
  860. +
  861. +
  862. +extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
  863. +/*
  864. + Close the file in zip opened with unzOpenCurrentFile
  865. + Return UNZ_CRCERROR if all the file was read but the CRC is not good
  866. +*/
  867. +
  868. +extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
  869. + voidp buf,
  870. + unsigned len));
  871. +/*
  872. + Read bytes from the current file (opened by unzOpenCurrentFile)
  873. + buf contain buffer where data must be copied
  874. + len the size of buf.
  875. +
  876. + return the number of byte copied if somes bytes are copied
  877. + return 0 if the end of file was reached
  878. + return <0 with error code if there is an error
  879. + (UNZ_ERRNO for IO error, or zLib error for uncompress error)
  880. +*/
  881. +
  882. +extern z_off_t ZEXPORT unztell OF((unzFile file));
  883. +
  884. +extern ZPOS64_T ZEXPORT unztell64 OF((unzFile file));
  885. +/*
  886. + Give the current position in uncompressed data
  887. +*/
  888. +
  889. +extern int ZEXPORT unzeof OF((unzFile file));
  890. +/*
  891. + return 1 if the end of file was reached, 0 elsewhere
  892. +*/
  893. +
  894. +extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
  895. + voidp buf,
  896. + unsigned len));
  897. +/*
  898. + Read extra field from the current file (opened by unzOpenCurrentFile)
  899. + This is the local-header version of the extra field (sometimes, there is
  900. + more info in the local-header version than in the central-header)
  901. +
  902. + if buf==NULL, it return the size of the local extra field
  903. +
  904. + if buf!=NULL, len is the size of the buffer, the extra header is copied in
  905. + buf.
  906. + the return value is the number of bytes copied in buf, or (if <0)
  907. + the error code
  908. +*/
  909. +
  910. +/***************************************************************************/
  911. +
  912. +/* Get the current file offset */
  913. +extern ZPOS64_T ZEXPORT unzGetOffset64 (unzFile file);
  914. +extern uLong ZEXPORT unzGetOffset (unzFile file);
  915. +
  916. +/* Set the current file offset */
  917. +extern int ZEXPORT unzSetOffset64 (unzFile file, ZPOS64_T pos);
  918. +extern int ZEXPORT unzSetOffset (unzFile file, uLong pos);
  919. +
  920. +
  921. +
  922. +#ifdef __cplusplus
  923. +}
  924. +#endif
  925. +
  926. +#endif /* _unz64_H */
  927. Index: include/zip.h
  928. ===================================================================
  929. --- include/zip.h (nonexistent)
  930. +++ include/zip.h (working copy)
  931. @@ -0,0 +1,362 @@
  932. +/* zip.h -- IO on .zip files using zlib
  933. + Version 1.1, February 14h, 2010
  934. + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
  935. +
  936. + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
  937. +
  938. + Modifications for Zip64 support
  939. + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
  940. +
  941. + For more info read MiniZip_info.txt
  942. +
  943. + ---------------------------------------------------------------------------
  944. +
  945. + Condition of use and distribution are the same than zlib :
  946. +
  947. + This software is provided 'as-is', without any express or implied
  948. + warranty. In no event will the authors be held liable for any damages
  949. + arising from the use of this software.
  950. +
  951. + Permission is granted to anyone to use this software for any purpose,
  952. + including commercial applications, and to alter it and redistribute it
  953. + freely, subject to the following restrictions:
  954. +
  955. + 1. The origin of this software must not be misrepresented; you must not
  956. + claim that you wrote the original software. If you use this software
  957. + in a product, an acknowledgment in the product documentation would be
  958. + appreciated but is not required.
  959. + 2. Altered source versions must be plainly marked as such, and must not be
  960. + misrepresented as being the original software.
  961. + 3. This notice may not be removed or altered from any source distribution.
  962. +
  963. + ---------------------------------------------------------------------------
  964. +
  965. + Changes
  966. +
  967. + See header of zip.h
  968. +
  969. +*/
  970. +
  971. +#ifndef _zip12_H
  972. +#define _zip12_H
  973. +
  974. +#ifdef __cplusplus
  975. +extern "C" {
  976. +#endif
  977. +
  978. +//#define HAVE_BZIP2
  979. +
  980. +#ifndef _ZLIB_H
  981. +#include "zlib.h"
  982. +#endif
  983. +
  984. +#ifndef _ZLIBIOAPI_H
  985. +#include "ioapi.h"
  986. +#endif
  987. +
  988. +#ifdef HAVE_BZIP2
  989. +#include "bzlib.h"
  990. +#endif
  991. +
  992. +#define Z_BZIP2ED 12
  993. +
  994. +#if defined(STRICTZIP) || defined(STRICTZIPUNZIP)
  995. +/* like the STRICT of WIN32, we define a pointer that cannot be converted
  996. + from (void*) without cast */
  997. +typedef struct TagzipFile__ { int unused; } zipFile__;
  998. +typedef zipFile__ *zipFile;
  999. +#else
  1000. +typedef voidp zipFile;
  1001. +#endif
  1002. +
  1003. +#define ZIP_OK (0)
  1004. +#define ZIP_EOF (0)
  1005. +#define ZIP_ERRNO (Z_ERRNO)
  1006. +#define ZIP_PARAMERROR (-102)
  1007. +#define ZIP_BADZIPFILE (-103)
  1008. +#define ZIP_INTERNALERROR (-104)
  1009. +
  1010. +#ifndef DEF_MEM_LEVEL
  1011. +# if MAX_MEM_LEVEL >= 8
  1012. +# define DEF_MEM_LEVEL 8
  1013. +# else
  1014. +# define DEF_MEM_LEVEL MAX_MEM_LEVEL
  1015. +# endif
  1016. +#endif
  1017. +/* default memLevel */
  1018. +
  1019. +/* tm_zip contain date/time info */
  1020. +typedef struct tm_zip_s
  1021. +{
  1022. + uInt tm_sec; /* seconds after the minute - [0,59] */
  1023. + uInt tm_min; /* minutes after the hour - [0,59] */
  1024. + uInt tm_hour; /* hours since midnight - [0,23] */
  1025. + uInt tm_mday; /* day of the month - [1,31] */
  1026. + uInt tm_mon; /* months since January - [0,11] */
  1027. + uInt tm_year; /* years - [1980..2044] */
  1028. +} tm_zip;
  1029. +
  1030. +typedef struct
  1031. +{
  1032. + tm_zip tmz_date; /* date in understandable format */
  1033. + uLong dosDate; /* if dos_date == 0, tmu_date is used */
  1034. +/* uLong flag; */ /* general purpose bit flag 2 bytes */
  1035. +
  1036. + uLong internal_fa; /* internal file attributes 2 bytes */
  1037. + uLong external_fa; /* external file attributes 4 bytes */
  1038. +} zip_fileinfo;
  1039. +
  1040. +typedef const char* zipcharpc;
  1041. +
  1042. +
  1043. +#define APPEND_STATUS_CREATE (0)
  1044. +#define APPEND_STATUS_CREATEAFTER (1)
  1045. +#define APPEND_STATUS_ADDINZIP (2)
  1046. +
  1047. +extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append));
  1048. +extern zipFile ZEXPORT zipOpen64 OF((const void *pathname, int append));
  1049. +/*
  1050. + Create a zipfile.
  1051. + pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on
  1052. + an Unix computer "zlib/zlib113.zip".
  1053. + if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip
  1054. + will be created at the end of the file.
  1055. + (useful if the file contain a self extractor code)
  1056. + if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will
  1057. + add files in existing zip (be sure you don't add file that doesn't exist)
  1058. + If the zipfile cannot be opened, the return value is NULL.
  1059. + Else, the return value is a zipFile Handle, usable with other function
  1060. + of this zip package.
  1061. +*/
  1062. +
  1063. +/* Note : there is no delete function into a zipfile.
  1064. + If you want delete file into a zipfile, you must open a zipfile, and create another
  1065. + Of couse, you can use RAW reading and writing to copy the file you did not want delte
  1066. +*/
  1067. +
  1068. +extern zipFile ZEXPORT zipOpen2 OF((const char *pathname,
  1069. + int append,
  1070. + zipcharpc* globalcomment,
  1071. + zlib_filefunc_def* pzlib_filefunc_def));
  1072. +
  1073. +extern zipFile ZEXPORT zipOpen2_64 OF((const void *pathname,
  1074. + int append,
  1075. + zipcharpc* globalcomment,
  1076. + zlib_filefunc64_def* pzlib_filefunc_def));
  1077. +
  1078. +extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file,
  1079. + const char* filename,
  1080. + const zip_fileinfo* zipfi,
  1081. + const void* extrafield_local,
  1082. + uInt size_extrafield_local,
  1083. + const void* extrafield_global,
  1084. + uInt size_extrafield_global,
  1085. + const char* comment,
  1086. + int method,
  1087. + int level));
  1088. +
  1089. +extern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file,
  1090. + const char* filename,
  1091. + const zip_fileinfo* zipfi,
  1092. + const void* extrafield_local,
  1093. + uInt size_extrafield_local,
  1094. + const void* extrafield_global,
  1095. + uInt size_extrafield_global,
  1096. + const char* comment,
  1097. + int method,
  1098. + int level,
  1099. + int zip64));
  1100. +
  1101. +/*
  1102. + Open a file in the ZIP for writing.
  1103. + filename : the filename in zip (if NULL, '-' without quote will be used
  1104. + *zipfi contain supplemental information
  1105. + if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local
  1106. + contains the extrafield data the the local header
  1107. + if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global
  1108. + contains the extrafield data the the local header
  1109. + if comment != NULL, comment contain the comment string
  1110. + method contain the compression method (0 for store, Z_DEFLATED for deflate)
  1111. + level contain the level of compression (can be Z_DEFAULT_COMPRESSION)
  1112. + zip64 is set to 1 if a zip64 extended information block should be added to the local file header.
  1113. + this MUST be '1' if the uncompressed size is >= 0xffffffff.
  1114. +
  1115. +*/
  1116. +
  1117. +
  1118. +extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file,
  1119. + const char* filename,
  1120. + const zip_fileinfo* zipfi,
  1121. + const void* extrafield_local,
  1122. + uInt size_extrafield_local,
  1123. + const void* extrafield_global,
  1124. + uInt size_extrafield_global,
  1125. + const char* comment,
  1126. + int method,
  1127. + int level,
  1128. + int raw));
  1129. +
  1130. +
  1131. +extern int ZEXPORT zipOpenNewFileInZip2_64 OF((zipFile file,
  1132. + const char* filename,
  1133. + const zip_fileinfo* zipfi,
  1134. + const void* extrafield_local,
  1135. + uInt size_extrafield_local,
  1136. + const void* extrafield_global,
  1137. + uInt size_extrafield_global,
  1138. + const char* comment,
  1139. + int method,
  1140. + int level,
  1141. + int raw,
  1142. + int zip64));
  1143. +/*
  1144. + Same than zipOpenNewFileInZip, except if raw=1, we write raw file
  1145. + */
  1146. +
  1147. +extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file,
  1148. + const char* filename,
  1149. + const zip_fileinfo* zipfi,
  1150. + const void* extrafield_local,
  1151. + uInt size_extrafield_local,
  1152. + const void* extrafield_global,
  1153. + uInt size_extrafield_global,
  1154. + const char* comment,
  1155. + int method,
  1156. + int level,
  1157. + int raw,
  1158. + int windowBits,
  1159. + int memLevel,
  1160. + int strategy,
  1161. + const char* password,
  1162. + uLong crcForCrypting));
  1163. +
  1164. +extern int ZEXPORT zipOpenNewFileInZip3_64 OF((zipFile file,
  1165. + const char* filename,
  1166. + const zip_fileinfo* zipfi,
  1167. + const void* extrafield_local,
  1168. + uInt size_extrafield_local,
  1169. + const void* extrafield_global,
  1170. + uInt size_extrafield_global,
  1171. + const char* comment,
  1172. + int method,
  1173. + int level,
  1174. + int raw,
  1175. + int windowBits,
  1176. + int memLevel,
  1177. + int strategy,
  1178. + const char* password,
  1179. + uLong crcForCrypting,
  1180. + int zip64
  1181. + ));
  1182. +
  1183. +/*
  1184. + Same than zipOpenNewFileInZip2, except
  1185. + windowBits,memLevel,,strategy : see parameter strategy in deflateInit2
  1186. + password : crypting password (NULL for no crypting)
  1187. + crcForCrypting : crc of file to compress (needed for crypting)
  1188. + */
  1189. +
  1190. +extern int ZEXPORT zipOpenNewFileInZip4 OF((zipFile file,
  1191. + const char* filename,
  1192. + const zip_fileinfo* zipfi,
  1193. + const void* extrafield_local,
  1194. + uInt size_extrafield_local,
  1195. + const void* extrafield_global,
  1196. + uInt size_extrafield_global,
  1197. + const char* comment,
  1198. + int method,
  1199. + int level,
  1200. + int raw,
  1201. + int windowBits,
  1202. + int memLevel,
  1203. + int strategy,
  1204. + const char* password,
  1205. + uLong crcForCrypting,
  1206. + uLong versionMadeBy,
  1207. + uLong flagBase
  1208. + ));
  1209. +
  1210. +
  1211. +extern int ZEXPORT zipOpenNewFileInZip4_64 OF((zipFile file,
  1212. + const char* filename,
  1213. + const zip_fileinfo* zipfi,
  1214. + const void* extrafield_local,
  1215. + uInt size_extrafield_local,
  1216. + const void* extrafield_global,
  1217. + uInt size_extrafield_global,
  1218. + const char* comment,
  1219. + int method,
  1220. + int level,
  1221. + int raw,
  1222. + int windowBits,
  1223. + int memLevel,
  1224. + int strategy,
  1225. + const char* password,
  1226. + uLong crcForCrypting,
  1227. + uLong versionMadeBy,
  1228. + uLong flagBase,
  1229. + int zip64
  1230. + ));
  1231. +/*
  1232. + Same than zipOpenNewFileInZip4, except
  1233. + versionMadeBy : value for Version made by field
  1234. + flag : value for flag field (compression level info will be added)
  1235. + */
  1236. +
  1237. +
  1238. +extern int ZEXPORT zipWriteInFileInZip OF((zipFile file,
  1239. + const void* buf,
  1240. + unsigned len));
  1241. +/*
  1242. + Write data in the zipfile
  1243. +*/
  1244. +
  1245. +extern int ZEXPORT zipCloseFileInZip OF((zipFile file));
  1246. +/*
  1247. + Close the current file in the zipfile
  1248. +*/
  1249. +
  1250. +extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file,
  1251. + uLong uncompressed_size,
  1252. + uLong crc32));
  1253. +
  1254. +extern int ZEXPORT zipCloseFileInZipRaw64 OF((zipFile file,
  1255. + ZPOS64_T uncompressed_size,
  1256. + uLong crc32));
  1257. +
  1258. +/*
  1259. + Close the current file in the zipfile, for file opened with
  1260. + parameter raw=1 in zipOpenNewFileInZip2
  1261. + uncompressed_size and crc32 are value for the uncompressed size
  1262. +*/
  1263. +
  1264. +extern int ZEXPORT zipClose OF((zipFile file,
  1265. + const char* global_comment));
  1266. +/*
  1267. + Close the zipfile
  1268. +*/
  1269. +
  1270. +
  1271. +extern int ZEXPORT zipRemoveExtraInfoBlock OF((char* pData, int* dataLen, short sHeader));
  1272. +/*
  1273. + zipRemoveExtraInfoBlock - Added by Mathias Svensson
  1274. +
  1275. + Remove extra information block from a extra information data for the local file header or central directory header
  1276. +
  1277. + It is needed to remove ZIP64 extra information blocks when before data is written if using RAW mode.
  1278. +
  1279. + 0x0001 is the signature header for the ZIP64 extra information blocks
  1280. +
  1281. + usage.
  1282. + Remove ZIP64 Extra information from a central director extra field data
  1283. + zipRemoveExtraInfoBlock(pCenDirExtraFieldData, &nCenDirExtraFieldDataLen, 0x0001);
  1284. +
  1285. + Remove ZIP64 Extra information from a Local File Header extra field data
  1286. + zipRemoveExtraInfoBlock(pLocalHeaderExtraFieldData, &nLocalHeaderExtraFieldDataLen, 0x0001);
  1287. +*/
  1288. +
  1289. +#ifdef __cplusplus
  1290. +}
  1291. +#endif
  1292. +
  1293. +#endif /* _zip64_H */
  1294. Index: src/Makefile.am
  1295. ===================================================================
  1296. --- src/Makefile.am (revision 4176)
  1297. +++ src/Makefile.am (working copy)
  1298. @@ -11,7 +11,7 @@
  1299. .rc.o:
  1300. $(WINDRES) -o $@ $<
  1301.  
  1302. -dosbox_SOURCES = dosbox.cpp $(ico_stuff)
  1303. +dosbox_SOURCES = dosbox.cpp save_state.cpp save_state.h miniunz.c minizip.c unzip.c zip.c ioapi.c mztools.c $(ico_stuff)
  1304. dosbox_LDADD = cpu/libcpu.a debug/libdebug.a dos/libdos.a fpu/libfpu.a hardware/libhardware.a gui/libgui.a \
  1305. ints/libints.a misc/libmisc.a shell/libshell.a hardware/mame/libmame.a \
  1306. hardware/serialport/libserial.a libs/gui_tk/libgui_tk.a
  1307. Index: src/cpu/core_dynrec/cache.h
  1308. ===================================================================
  1309. --- src/cpu/core_dynrec/cache.h (revision 4176)
  1310. +++ src/cpu/core_dynrec/cache.h (working copy)
  1311. @@ -663,3 +663,75 @@
  1312. cache_code_link_blocks = NULL;
  1313. cache_initialized = false; */
  1314. }
  1315. +
  1316. +static void cache_reset(void) {
  1317. + if (cache_initialized) {
  1318. + for (;;) {
  1319. + if (cache.used_pages) {
  1320. + CodePageHandlerDynRec * cpage=cache.used_pages;
  1321. + CodePageHandlerDynRec * npage=cache.used_pages->next;
  1322. + cpage->ClearRelease();
  1323. + delete cpage;
  1324. + cache.used_pages=npage;
  1325. + } else break;
  1326. + }
  1327. +
  1328. + if (cache_blocks == NULL) {
  1329. + cache_blocks=(CacheBlockDynRec*)malloc(CACHE_BLOCKS*sizeof(CacheBlockDynRec));
  1330. + if(!cache_blocks) E_Exit("Allocating cache_blocks has failed");
  1331. + }
  1332. + memset(cache_blocks,0,sizeof(CacheBlockDynRec)*CACHE_BLOCKS);
  1333. + cache.block.free=&cache_blocks[0];
  1334. + for (Bits i=0;i<CACHE_BLOCKS-1;i++) {
  1335. + cache_blocks[i].link[0].to=(CacheBlockDynRec *)1;
  1336. + cache_blocks[i].link[1].to=(CacheBlockDynRec *)1;
  1337. + cache_blocks[i].cache.next=&cache_blocks[i+1];
  1338. + }
  1339. +
  1340. + if (cache_code_start_ptr==NULL) {
  1341. +#if defined (WIN32)
  1342. + cache_code_start_ptr=(Bit8u*)VirtualAlloc(0,CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP-1+PAGESIZE_TEMP,
  1343. + MEM_COMMIT,PAGE_EXECUTE_READWRITE);
  1344. + if (!cache_code_start_ptr)
  1345. + cache_code_start_ptr=(Bit8u*)malloc(CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP-1+PAGESIZE_TEMP);
  1346. +#else
  1347. + cache_code_start_ptr=(Bit8u*)malloc(CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP-1+PAGESIZE_TEMP);
  1348. +#endif
  1349. + if (!cache_code_start_ptr) E_Exit("Allocating dynamic cache failed");
  1350. +
  1351. + cache_code=(Bit8u*)(((Bitu)cache_code_start_ptr + PAGESIZE_TEMP-1) & ~(PAGESIZE_TEMP-1)); //Bitu is same size as a pointer.
  1352. +
  1353. + cache_code_link_blocks=cache_code;
  1354. + cache_code+=PAGESIZE_TEMP;
  1355. +
  1356. +#if (C_HAVE_MPROTECT)
  1357. + if(mprotect(cache_code_link_blocks,CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP,PROT_WRITE|PROT_READ|PROT_EXEC))
  1358. + LOG_MSG("Setting excute permission on the code cache has failed!");
  1359. +#endif
  1360. + }
  1361. +
  1362. + CacheBlockDynRec * block=cache_getblock();
  1363. + cache.block.first=block;
  1364. + cache.block.active=block;
  1365. + block->cache.start=&cache_code[0];
  1366. + block->cache.size=CACHE_TOTAL;
  1367. + block->cache.next=0; //Last block in the list
  1368. +
  1369. + /* Setup the default blocks for block linkage returns */
  1370. + cache.pos=&cache_code_link_blocks[0];
  1371. + link_blocks[0].cache.start=cache.pos;
  1372. + dyn_return(BR_Link1,false);
  1373. + cache.pos=&cache_code_link_blocks[32];
  1374. + link_blocks[1].cache.start=cache.pos;
  1375. + dyn_return(BR_Link2,false);
  1376. + cache.free_pages=0;
  1377. + cache.last_page=0;
  1378. + cache.used_pages=0;
  1379. + /* Setup the code pages */
  1380. + for (Bitu i=0;i<CACHE_PAGES;i++) {
  1381. + CodePageHandlerDynRec * newpage=new CodePageHandlerDynRec();
  1382. + newpage->next=cache.free_pages;
  1383. + cache.free_pages=newpage;
  1384. + }
  1385. + }
  1386. +}
  1387. Index: src/cpu/core_dynrec.cpp
  1388. ===================================================================
  1389. --- src/cpu/core_dynrec.cpp (revision 4176)
  1390. +++ src/cpu/core_dynrec.cpp (working copy)
  1391. @@ -335,4 +335,8 @@
  1392. cache_close();
  1393. }
  1394.  
  1395. +void CPU_Core_Dynrec_Cache_Reset(void) {
  1396. + cache_reset();
  1397. +}
  1398. +
  1399. #endif
  1400. Index: src/cpu/cpu.cpp
  1401. ===================================================================
  1402. --- src/cpu/cpu.cpp (revision 4176)
  1403. +++ src/cpu/cpu.cpp (working copy)
  1404. @@ -23,6 +23,9 @@
  1405. #include "dosbox.h"
  1406. #include "cpu.h"
  1407. #include "memory.h"
  1408. +
  1409. +#include "../save_state.h"
  1410. +
  1411. #include "debug.h"
  1412. #include "mapper.h"
  1413. #include "setup.h"
  1414. @@ -75,11 +78,13 @@
  1415. void CPU_Core_Dyn_X86_Init(void);
  1416. void CPU_Core_Dyn_X86_Cache_Init(bool enable_cache);
  1417. void CPU_Core_Dyn_X86_Cache_Close(void);
  1418. +void CPU_Core_Dyn_X86_Cache_Reset(void);
  1419. void CPU_Core_Dyn_X86_SetFPUMode(bool dh_fpu);
  1420. #elif (C_DYNREC)
  1421. void CPU_Core_Dynrec_Init(void);
  1422. void CPU_Core_Dynrec_Cache_Init(bool enable_cache);
  1423. void CPU_Core_Dynrec_Cache_Close(void);
  1424. +void CPU_Core_Dynrec_Cache_Reset(void);
  1425. #endif
  1426.  
  1427. /* In debug mode exceptions are tested and dosbox exits when
  1428. @@ -331,6 +336,10 @@
  1429. is386=desc.Is386();
  1430. return true;
  1431. }
  1432. +
  1433. + void SaveState( std::ostream& stream );
  1434. + void LoadState( std::istream& stream );
  1435. +
  1436. TSS_Descriptor desc;
  1437. Bitu selector;
  1438. PhysPt base;
  1439. @@ -2404,6 +2413,10 @@
  1440. if(CPU_CycleDown <= 0) CPU_CycleDown = 20;
  1441. if (CPU_CycleAutoAdjust) GFX_SetTitle(CPU_CyclePercUsed,-1,false);
  1442. else GFX_SetTitle(CPU_CycleMax,-1,false);
  1443. +
  1444. + // savestate support
  1445. + cpu.hlt.old_decoder=cpudecoder;
  1446. +
  1447. return true;
  1448. }
  1449. ~CPU(){ /* empty */};
  1450. @@ -2426,3 +2439,318 @@
  1451. }
  1452. //initialize static members
  1453. bool CPU::inited=false;
  1454. +
  1455. +//save state support
  1456. +void DescriptorTable::SaveState( std::ostream& stream )
  1457. +{
  1458. + WRITE_POD( &table_base, table_base );
  1459. + WRITE_POD( &table_limit, table_limit );
  1460. +}
  1461. +
  1462. +
  1463. +void DescriptorTable::LoadState( std::istream& stream )
  1464. +{
  1465. + READ_POD( &table_base, table_base );
  1466. + READ_POD( &table_limit, table_limit );
  1467. +}
  1468. +
  1469. +
  1470. +void GDTDescriptorTable::SaveState(std::ostream& stream)
  1471. +{
  1472. + this->DescriptorTable::SaveState(stream);
  1473. +
  1474. +
  1475. + WRITE_POD( &ldt_base, ldt_base );
  1476. + WRITE_POD( &ldt_limit, ldt_limit );
  1477. + WRITE_POD( &ldt_value, ldt_value );
  1478. +}
  1479. +
  1480. +
  1481. +void GDTDescriptorTable::LoadState(std::istream& stream)
  1482. +{
  1483. + this->DescriptorTable::LoadState(stream);
  1484. +
  1485. +
  1486. + READ_POD( &ldt_base, ldt_base );
  1487. + READ_POD( &ldt_limit, ldt_limit );
  1488. + READ_POD( &ldt_value, ldt_value );
  1489. +}
  1490. +
  1491. +
  1492. +void TaskStateSegment::SaveState( std::ostream& stream )
  1493. +{
  1494. + WRITE_POD( &desc.saved, desc.saved );
  1495. + WRITE_POD( &selector, selector );
  1496. + WRITE_POD( &base, base );
  1497. + WRITE_POD( &limit, limit );
  1498. + WRITE_POD( &is386, is386 );
  1499. + WRITE_POD( &valid, valid );
  1500. +}
  1501. +
  1502. +
  1503. +void TaskStateSegment::LoadState( std::istream& stream )
  1504. +{
  1505. + READ_POD( &desc.saved, desc.saved );
  1506. + READ_POD( &selector, selector );
  1507. + READ_POD( &base, base );
  1508. + READ_POD( &limit, limit );
  1509. + READ_POD( &is386, is386 );
  1510. + READ_POD( &valid, valid );
  1511. +}
  1512. +
  1513. +
  1514. +Bit16u CPU_FindDecoderType( CPU_Decoder *decoder )
  1515. +{
  1516. + Bit16u decoder_idx;
  1517. +
  1518. + decoder_idx = 0xffff;
  1519. +
  1520. +
  1521. + if(0) {}
  1522. + else if( cpudecoder == &CPU_Core_Normal_Run ) decoder_idx = 0;
  1523. + else if( cpudecoder == &CPU_Core_Prefetch_Run ) decoder_idx = 1;
  1524. + else if( cpudecoder == &CPU_Core_Simple_Run ) decoder_idx = 2;
  1525. + else if( cpudecoder == &CPU_Core_Full_Run ) decoder_idx = 3;
  1526. + else if( cpudecoder == &CPU_Core_Normal_Trap_Run ) decoder_idx = 100;
  1527. +#if (C_DYNAMIC_X86)
  1528. +else if( cpudecoder == &CPU_Core_Dyn_X86_Run ) decoder_idx = 4;
  1529. +#endif
  1530. +#if (C_DYNREC)
  1531. +else if( cpudecoder == &CPU_Core_Dynrec_Run ) decoder_idx = 5;
  1532. +#endif
  1533. +
  1534. +else if( cpudecoder == &CPU_Core_Normal_Trap_Run ) decoder_idx = 100;
  1535. +#if (C_DYNAMIC_X86)
  1536. +else if( cpudecoder == &CPU_Core_Dyn_X86_Trap_Run ) decoder_idx = 101;
  1537. +#endif
  1538. +#if(C_DYNREC)
  1539. +else if( cpudecoder == &CPU_Core_Dynrec_Trap_Run ) decoder_idx = 102;
  1540. +#endif
  1541. +
  1542. +else if( cpudecoder == &HLT_Decode ) decoder_idx = 200;
  1543. +
  1544. +
  1545. +return decoder_idx;
  1546. +}
  1547. +
  1548. +
  1549. +CPU_Decoder *CPU_IndexDecoderType( Bit16u decoder_idx )
  1550. +{
  1551. +CPU_Decoder *cpudecoder;
  1552. +
  1553. +
  1554. +cpudecoder = 0;
  1555. +switch( decoder_idx ) {
  1556. + case 0: cpudecoder = &CPU_Core_Normal_Run; break;
  1557. + case 1: cpudecoder = &CPU_Core_Prefetch_Run; break;
  1558. + case 2: cpudecoder = &CPU_Core_Simple_Run; break;
  1559. + case 3: cpudecoder = &CPU_Core_Full_Run; break;
  1560. +#if (C_DYNAMIC_X86)
  1561. + case 4: cpudecoder = &CPU_Core_Dyn_X86_Run; break;
  1562. +#endif
  1563. +#if (C_DYNREC)
  1564. + case 5: cpudecoder = &CPU_Core_Dynrec_Run; break;
  1565. +#endif
  1566. +
  1567. + case 100: cpudecoder = &CPU_Core_Normal_Trap_Run; break;
  1568. +#if (C_DYNAMIC_X86)
  1569. + case 101: cpudecoder = &CPU_Core_Dyn_X86_Trap_Run; break;
  1570. +#endif
  1571. +#if (C_DYNREC)
  1572. + case 102: cpudecoder = &CPU_Core_Dynrec_Trap_Run; break;
  1573. +#endif
  1574. +
  1575. + case 200: cpudecoder = &HLT_Decode; break;
  1576. +}
  1577. +
  1578. +
  1579. +return cpudecoder;
  1580. +}
  1581. +
  1582. +extern void POD_Save_CPU_Flags( std::ostream& stream );
  1583. +extern void POD_Save_CPU_Paging( std::ostream& stream );
  1584. +extern void POD_Load_CPU_Flags( std::istream& stream );
  1585. +extern void POD_Load_CPU_Paging( std::istream& stream );
  1586. +
  1587. +#if (C_DYNAMIC_X86)
  1588. +extern void CPU_Core_Dyn_X86_Cache_Reset(void);
  1589. +#endif
  1590. +
  1591. +namespace
  1592. +{
  1593. +class SerializeCPU : public SerializeGlobalPOD
  1594. +{
  1595. +public:
  1596. +SerializeCPU() : SerializeGlobalPOD("CPU")
  1597. +{}
  1598. +
  1599. +private:
  1600. +virtual void getBytes(std::ostream& stream)
  1601. +{
  1602. + Bit16u decoder_idx;
  1603. +
  1604. + extern Bits PageFaultCore(void);
  1605. + extern Bits IOFaultCore(void);
  1606. +
  1607. +
  1608. +
  1609. + decoder_idx = CPU_FindDecoderType( cpudecoder );
  1610. +
  1611. + //********************************************
  1612. + //********************************************
  1613. + //********************************************
  1614. +
  1615. + SerializeGlobalPOD::getBytes(stream);
  1616. +
  1617. +
  1618. + // - pure data
  1619. + WRITE_POD( &cpu_regs, cpu_regs );
  1620. +
  1621. + WRITE_POD( &cpu.cpl, cpu.cpl );
  1622. + WRITE_POD( &cpu.mpl, cpu.mpl );
  1623. + WRITE_POD( &cpu.cr0, cpu.cr0 );
  1624. + WRITE_POD( &cpu.pmode, cpu.pmode );
  1625. + cpu.gdt.SaveState(stream);
  1626. + cpu.idt.SaveState(stream);
  1627. + WRITE_POD( &cpu.stack, cpu.stack );
  1628. + WRITE_POD( &cpu.code, cpu.code );
  1629. + WRITE_POD( &cpu.hlt.cs, cpu.hlt.cs );
  1630. + WRITE_POD( &cpu.hlt.eip, cpu.hlt.eip );
  1631. + WRITE_POD( &cpu.exception, cpu.exception );
  1632. + WRITE_POD( &cpu.direction, cpu.direction );
  1633. + WRITE_POD( &cpu.trap_skip, cpu.trap_skip );
  1634. + WRITE_POD( &cpu.drx, cpu.drx );
  1635. + WRITE_POD( &cpu.trx, cpu.trx );
  1636. +
  1637. + WRITE_POD( &Segs, Segs );
  1638. + WRITE_POD( &CPU_Cycles, CPU_Cycles );
  1639. + WRITE_POD( &CPU_CycleLeft, CPU_CycleLeft );
  1640. + WRITE_POD( &CPU_IODelayRemoved, CPU_IODelayRemoved );
  1641. + cpu_tss.SaveState(stream);
  1642. + WRITE_POD( &lastint, lastint );
  1643. +
  1644. + //********************************************
  1645. + //********************************************
  1646. + //********************************************
  1647. +
  1648. + // - reloc func ptr
  1649. + WRITE_POD( &decoder_idx, decoder_idx );
  1650. +
  1651. + POD_Save_CPU_Flags(stream);
  1652. + POD_Save_CPU_Paging(stream);
  1653. +}
  1654. +
  1655. +virtual void setBytes(std::istream& stream)
  1656. +{
  1657. + Bit16u decoder_idx;
  1658. + Bit16u decoder_old;
  1659. +
  1660. +
  1661. +
  1662. +
  1663. +
  1664. + decoder_old = CPU_FindDecoderType( cpudecoder );
  1665. +
  1666. + //********************************************
  1667. + //********************************************
  1668. + //********************************************
  1669. +
  1670. + SerializeGlobalPOD::setBytes(stream);
  1671. +
  1672. +
  1673. + // - pure data
  1674. + READ_POD( &cpu_regs, cpu_regs );
  1675. +
  1676. + READ_POD( &cpu.cpl, cpu.cpl );
  1677. + READ_POD( &cpu.mpl, cpu.mpl );
  1678. + READ_POD( &cpu.cr0, cpu.cr0 );
  1679. + READ_POD( &cpu.pmode, cpu.pmode );
  1680. + cpu.gdt.LoadState(stream);
  1681. + cpu.idt.LoadState(stream);
  1682. + READ_POD( &cpu.stack, cpu.stack );
  1683. + READ_POD( &cpu.code, cpu.code );
  1684. + READ_POD( &cpu.hlt.cs, cpu.hlt.cs );
  1685. + READ_POD( &cpu.hlt.eip, cpu.hlt.eip );
  1686. + READ_POD( &cpu.exception, cpu.exception );
  1687. + READ_POD( &cpu.direction, cpu.direction );
  1688. + READ_POD( &cpu.trap_skip, cpu.trap_skip );
  1689. + READ_POD( &cpu.drx, cpu.drx );
  1690. + READ_POD( &cpu.trx, cpu.trx );
  1691. +
  1692. + READ_POD( &Segs, Segs );
  1693. + READ_POD( &CPU_Cycles, CPU_Cycles );
  1694. + READ_POD( &CPU_CycleLeft, CPU_CycleLeft );
  1695. + READ_POD( &CPU_IODelayRemoved, CPU_IODelayRemoved );
  1696. + cpu_tss.LoadState(stream);
  1697. + READ_POD( &lastint, lastint );
  1698. +
  1699. + //********************************************
  1700. + //********************************************
  1701. + //********************************************
  1702. +
  1703. + // - reloc func ptr
  1704. + READ_POD( &decoder_idx, decoder_idx );
  1705. +
  1706. +
  1707. +
  1708. + POD_Load_CPU_Flags(stream);
  1709. + POD_Load_CPU_Paging(stream);
  1710. +
  1711. + //*******************************************
  1712. + //*******************************************
  1713. + //*******************************************
  1714. +
  1715. + // switch to running core
  1716. + if( decoder_idx < 100 ) {
  1717. + switch( decoder_old ) {
  1718. + // run -> run (0-99)
  1719. +
  1720. + // trap -> run
  1721. + case 100: cpudecoder = CPU_IndexDecoderType(0); break;
  1722. + case 101: cpudecoder = CPU_IndexDecoderType(4); break;
  1723. + case 102: cpudecoder = CPU_IndexDecoderType(5); break;
  1724. +
  1725. + // hlt -> run
  1726. + case 200: cpudecoder = cpu.hlt.old_decoder; break;
  1727. + }
  1728. + }
  1729. +
  1730. + // switch to trap core
  1731. + else if( decoder_idx < 200 ) {
  1732. + switch( decoder_old ) {
  1733. + // run -> trap
  1734. + case 0:
  1735. + case 1:
  1736. + case 2:
  1737. + case 3: cpudecoder = CPU_IndexDecoderType(100); break;
  1738. + case 4: cpudecoder = CPU_IndexDecoderType(101); break;
  1739. + case 5: cpudecoder = CPU_IndexDecoderType(102); break;
  1740. +
  1741. + // trap -> trap (100-199)
  1742. +
  1743. + // hlt -> trap
  1744. + case 200: {
  1745. + switch( CPU_FindDecoderType(cpu.hlt.old_decoder) ) {
  1746. + case 0:
  1747. + case 1:
  1748. + case 2:
  1749. + case 3: cpudecoder = CPU_IndexDecoderType(100); break;
  1750. + case 4: cpudecoder = CPU_IndexDecoderType(101); break;
  1751. + case 5: cpudecoder = CPU_IndexDecoderType(102); break;
  1752. + }
  1753. + }
  1754. + }
  1755. + }
  1756. +
  1757. + // switch to hlt core
  1758. + else if( decoder_idx < 300 ) {
  1759. + cpudecoder = CPU_IndexDecoderType(200);
  1760. + }
  1761. +#if (C_DYNAMIC_X86)
  1762. + CPU_Core_Dyn_X86_Cache_Reset();
  1763. +#elif (C_DYNREC)
  1764. + CPU_Core_Dynrec_Cache_Reset();
  1765. +#endif
  1766. +}
  1767. +} dummy;
  1768. +}
  1769. Index: src/cpu/flags.cpp
  1770. ===================================================================
  1771. --- src/cpu/flags.cpp (revision 4176)
  1772. +++ src/cpu/flags.cpp (working copy)
  1773. @@ -26,6 +26,8 @@
  1774. #include "lazyflags.h"
  1775. #include "pic.h"
  1776.  
  1777. +#include "../save_state.h"
  1778. +
  1779. LazyFlags lflags;
  1780.  
  1781. /* CF Carry Flag -- Set on high-order bit carry or borrow; cleared
  1782. @@ -1186,3 +1188,16 @@
  1783. }
  1784.  
  1785. #endif
  1786. +
  1787. +// save state support
  1788. +void POD_Save_CPU_Flags( std::ostream& stream )
  1789. +{
  1790. + // - pure data
  1791. + WRITE_POD( &lflags, lflags );
  1792. +}
  1793. +
  1794. +void POD_Load_CPU_Flags( std::istream& stream )
  1795. +{
  1796. + // - pure data
  1797. + READ_POD( &lflags, lflags );
  1798. +}
  1799. \ No newline at end of file
  1800. Index: src/cpu/paging.cpp
  1801. ===================================================================
  1802. --- src/cpu/paging.cpp (revision 4176)
  1803. +++ src/cpu/paging.cpp (working copy)
  1804. @@ -29,6 +29,7 @@
  1805. #include "cpu.h"
  1806. #include "debug.h"
  1807. #include "setup.h"
  1808. +#include "../save_state.h"
  1809.  
  1810. #define LINK_TOTAL (64*1024)
  1811.  
  1812. @@ -888,3 +889,137 @@
  1813. void PAGING_Init(Section * sec) {
  1814. test = new PAGING(sec);
  1815. }
  1816. +
  1817. +// save state support
  1818. +void POD_Save_CPU_Paging( std::ostream& stream )
  1819. +{
  1820. + WRITE_POD( &paging.cr3, paging.cr3 );
  1821. + WRITE_POD( &paging.cr2, paging.cr2 );
  1822. +// WRITE_POD( &paging.wp, paging.wp );
  1823. + WRITE_POD( &paging.base, paging.base );
  1824. +
  1825. + WRITE_POD( &paging.tlb.read, paging.tlb.read );
  1826. + WRITE_POD( &paging.tlb.write, paging.tlb.write );
  1827. + WRITE_POD( &paging.tlb.phys_page, paging.tlb.phys_page );
  1828. +
  1829. + WRITE_POD( &paging.links, paging.links );
  1830. +// WRITE_POD( &paging.ur_links, paging.ur_links );
  1831. +// WRITE_POD( &paging.krw_links, paging.krw_links );
  1832. +// WRITE_POD( &paging.kr_links, paging.kr_links );
  1833. +
  1834. + WRITE_POD( &paging.firstmb, paging.firstmb );
  1835. + WRITE_POD( &paging.enabled, paging.enabled );
  1836. +
  1837. + WRITE_POD( &pf_queue, pf_queue );
  1838. +}
  1839. +
  1840. +
  1841. +void POD_Load_CPU_Paging( std::istream& stream )
  1842. +{
  1843. + READ_POD( &paging.cr3, paging.cr3 );
  1844. + READ_POD( &paging.cr2, paging.cr2 );
  1845. +// READ_POD( &paging.wp, paging.wp );
  1846. + READ_POD( &paging.base, paging.base );
  1847. +
  1848. + READ_POD( &paging.tlb.read, paging.tlb.read );
  1849. + READ_POD( &paging.tlb.write, paging.tlb.write );
  1850. + READ_POD( &paging.tlb.phys_page, paging.tlb.phys_page );
  1851. +
  1852. + READ_POD( &paging.links, paging.links );
  1853. +// READ_POD( &paging.ur_links, paging.ur_links );
  1854. +// READ_POD( &paging.krw_links, paging.krw_links );
  1855. +// READ_POD( &paging.kr_links, paging.kr_links );
  1856. +
  1857. + READ_POD( &paging.firstmb, paging.firstmb );
  1858. + READ_POD( &paging.enabled, paging.enabled );
  1859. +
  1860. + READ_POD( &pf_queue, pf_queue );
  1861. +
  1862. + // reset all information
  1863. + paging.links.used = PAGING_LINKS;
  1864. + PAGING_ClearTLB();
  1865. +
  1866. + for( int lcv=0; lcv<TLB_SIZE; lcv++ ) {
  1867. + paging.tlb.read[lcv] = 0;
  1868. + paging.tlb.write[lcv] = 0;
  1869. + paging.tlb.readhandler[lcv] = &init_page_handler;
  1870. + paging.tlb.writehandler[lcv] = &init_page_handler;
  1871. + }
  1872. +}
  1873. +
  1874. +
  1875. +
  1876. +/*
  1877. +ykhwong 2012-05-21
  1878. +
  1879. +
  1880. +struct PagingBlock
  1881. + // - pure data
  1882. + Bitu cr3;
  1883. + Bitu cr2;
  1884. + bool wp;
  1885. +
  1886. +
  1887. + // - pure struct data
  1888. + struct {
  1889. + Bitu page;
  1890. + PhysPt addr;
  1891. + } base;
  1892. +
  1893. +
  1894. +#if defined(USE_FULL_TLB)
  1895. + struct {
  1896. + // - pure data
  1897. + HostPt read[TLB_SIZE];
  1898. + HostPt write[TLB_SIZE];
  1899. +
  1900. + // - reloc ptr
  1901. + PageHandler * readhandler[TLB_SIZE];
  1902. + PageHandler * writehandler[TLB_SIZE];
  1903. +
  1904. + // - pure data
  1905. + Bit32u phys_page[TLB_SIZE];
  1906. + } tlb;
  1907. +#else
  1908. + tlb_entry tlbh[TLB_SIZE];
  1909. + tlb_entry *tlbh_banks[TLB_BANKS];
  1910. +#endif
  1911. +
  1912. +
  1913. + // - pure struct data
  1914. + struct {
  1915. + Bitu used;
  1916. + Bit32u entries[PAGING_LINKS];
  1917. + } links;
  1918. +
  1919. + struct {
  1920. + Bitu used;
  1921. + Bit32u entries[PAGING_LINKS];
  1922. + } ur_links;
  1923. +
  1924. + struct {
  1925. + Bitu used;
  1926. + Bit32u entries[PAGING_LINKS];
  1927. + } krw_links;
  1928. +
  1929. + struct {
  1930. + Bitu used;
  1931. + Bit32u entries[PAGING_LINKS];
  1932. + } kr_links; // WP-only
  1933. +
  1934. + Bit32u firstmb[LINK_START];
  1935. + bool enabled;
  1936. +
  1937. +
  1938. +
  1939. +
  1940. +struct pf_queue
  1941. + // - pure data
  1942. + Bitu used;
  1943. + PF_Entry entries[PF_QUEUESIZE];
  1944. + // - pure data
  1945. + Bitu cs;
  1946. + Bitu eip;
  1947. + Bitu page_addr;
  1948. + Bitu mpl;
  1949. +*/
  1950. Index: src/dos/dev_con.h
  1951. ===================================================================
  1952. --- src/dos/dev_con.h (revision 4176)
  1953. +++ src/dos/dev_con.h (working copy)
  1954. @@ -33,6 +33,9 @@
  1955. Bit16u GetInformation(void);
  1956. bool ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode){return false;}
  1957. bool WriteToControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode){return false;}
  1958. +
  1959. + // virtual void SaveState( std::ostream& stream );
  1960. + // virtual void LoadState( std::istream& stream );
  1961. private:
  1962. void ClearAnsi(void);
  1963. void Output(Bit8u chr);
  1964. @@ -438,3 +441,21 @@
  1965. INT10_TeletypeOutputAttr(chr,ansi.attr,true);
  1966. } else INT10_TeletypeOutput(chr,7);
  1967. }
  1968. +
  1969. +/*// save state support
  1970. +void device_CON::SaveState( std::ostream& stream )
  1971. +{
  1972. + // - pure data
  1973. + WRITE_POD( &readcache, readcache );
  1974. +
  1975. + WRITE_POD( &ansi, ansi );
  1976. +}
  1977. +
  1978. +
  1979. +void device_CON::LoadState( std::istream& stream )
  1980. +{
  1981. + // - pure data
  1982. + READ_POD( &readcache, readcache );
  1983. +
  1984. + READ_POD( &ansi, ansi );
  1985. +}*/
  1986. Index: src/dos/dos.cpp
  1987. ===================================================================
  1988. --- src/dos/dos.cpp (revision 4176)
  1989. +++ src/dos/dos.cpp (working copy)
  1990. @@ -30,6 +30,8 @@
  1991. #include "support.h"
  1992. #include "serialport.h"
  1993.  
  1994. +#include "../save_state.h"
  1995. +
  1996. DOS_Block dos;
  1997. DOS_InfoBlock dos_infoblock;
  1998.  
  1999. @@ -1274,3 +1276,100 @@
  2000. /* shutdown function */
  2001. sec->AddDestroyFunction(&DOS_ShutDown,false);
  2002. }
  2003. +
  2004. +//save state support
  2005. +
  2006. +extern void POD_Save_DOS_Devices( std::ostream& stream );
  2007. +extern void POD_Save_DOS_DriveManager( std::ostream& stream );
  2008. +extern void POD_Save_DOS_Files( std::ostream& stream );
  2009. +extern void POD_Save_DOS_Memory( std::ostream& stream);
  2010. +extern void POD_Save_DOS_Mscdex( std::ostream& stream );
  2011. +extern void POD_Save_DOS_Tables( std::ostream& stream );
  2012. +
  2013. +extern void POD_Load_DOS_Devices( std::istream& stream );
  2014. +extern void POD_Load_DOS_DriveManager( std::istream& stream );
  2015. +extern void POD_Load_DOS_Files( std::istream& stream );
  2016. +extern void POD_Load_DOS_Memory( std::istream& stream );
  2017. +extern void POD_Load_DOS_Mscdex( std::istream& stream );
  2018. +extern void POD_Load_DOS_Tables( std::istream& stream );
  2019. +
  2020. +namespace
  2021. +{
  2022. +class SerializeDos : public SerializeGlobalPOD
  2023. +{
  2024. +public:
  2025. + SerializeDos() : SerializeGlobalPOD("Dos")
  2026. + {}
  2027. +
  2028. +private:
  2029. + virtual void getBytes(std::ostream& stream)
  2030. + {
  2031. + SerializeGlobalPOD::getBytes(stream);
  2032. +
  2033. + //***********************************************
  2034. + //***********************************************
  2035. + //***********************************************
  2036. + // - pure data
  2037. + WRITE_POD( &dos_copybuf, dos_copybuf );
  2038. +
  2039. + // - pure data
  2040. + WRITE_POD( &dos.firstMCB, dos.firstMCB );
  2041. + WRITE_POD( &dos.errorcode, dos.errorcode );
  2042. + WRITE_POD( &dos.env, dos.env );
  2043. + WRITE_POD( &dos.cpmentry, dos.cpmentry );
  2044. + WRITE_POD( &dos.return_code, dos.return_code );
  2045. + WRITE_POD( &dos.return_mode, dos.return_mode );
  2046. +
  2047. + WRITE_POD( &dos.current_drive, dos.current_drive );
  2048. + WRITE_POD( &dos.verify, dos.verify );
  2049. + WRITE_POD( &dos.breakcheck, dos.breakcheck );
  2050. + WRITE_POD( &dos.echo, dos.echo );
  2051. + WRITE_POD( &dos.direct_output, dos.direct_output );
  2052. + WRITE_POD( &dos.internal_output, dos.internal_output );
  2053. +
  2054. + WRITE_POD( &dos.loaded_codepage, dos.loaded_codepage );
  2055. +
  2056. + POD_Save_DOS_Devices(stream);
  2057. + POD_Save_DOS_DriveManager(stream);
  2058. + POD_Save_DOS_Files(stream);
  2059. + POD_Save_DOS_Memory(stream);
  2060. + POD_Save_DOS_Mscdex(stream);
  2061. + POD_Save_DOS_Tables(stream);
  2062. + }
  2063. +
  2064. + virtual void setBytes(std::istream& stream)
  2065. + {
  2066. + SerializeGlobalPOD::setBytes(stream);
  2067. +
  2068. + //***********************************************
  2069. + //***********************************************
  2070. + //***********************************************
  2071. + // - pure data
  2072. + READ_POD( &dos_copybuf, dos_copybuf );
  2073. +
  2074. + // - pure data
  2075. + READ_POD( &dos.firstMCB, dos.firstMCB );
  2076. + READ_POD( &dos.errorcode, dos.errorcode );
  2077. + READ_POD( &dos.env, dos.env );
  2078. + READ_POD( &dos.cpmentry, dos.cpmentry );
  2079. + READ_POD( &dos.return_code, dos.return_code );
  2080. + READ_POD( &dos.return_mode, dos.return_mode );
  2081. +
  2082. + READ_POD( &dos.current_drive, dos.current_drive );
  2083. + READ_POD( &dos.verify, dos.verify );
  2084. + READ_POD( &dos.breakcheck, dos.breakcheck );
  2085. + READ_POD( &dos.echo, dos.echo );
  2086. + READ_POD( &dos.direct_output, dos.direct_output );
  2087. + READ_POD( &dos.internal_output, dos.internal_output );
  2088. +
  2089. + READ_POD( &dos.loaded_codepage, dos.loaded_codepage );
  2090. +
  2091. + POD_Load_DOS_Devices(stream);
  2092. + POD_Load_DOS_DriveManager(stream);
  2093. + POD_Load_DOS_Files(stream);
  2094. + POD_Load_DOS_Memory(stream);
  2095. + POD_Load_DOS_Mscdex(stream);
  2096. + POD_Load_DOS_Tables(stream);
  2097. + }
  2098. +} dummy;
  2099. +}
  2100. \ No newline at end of file
  2101. Index: src/dos/dos_devices.cpp
  2102. ===================================================================
  2103. --- src/dos/dos_devices.cpp (revision 4176)
  2104. +++ src/dos/dos_devices.cpp (working copy)
  2105. @@ -28,6 +28,7 @@
  2106. #include "drives.h" //Wildcmp
  2107. /* Include all the devices */
  2108.  
  2109. +#include "../save_state.h"
  2110. #include "dev_con.h"
  2111.  
  2112.  
  2113. @@ -194,3 +195,17 @@
  2114. newdev3=new device_LPT1();
  2115. DOS_AddDevice(newdev3);
  2116. }
  2117. +
  2118. +// save state support
  2119. +void POD_Save_DOS_Devices( std::ostream& stream )
  2120. +{
  2121. + if( strcmp( Devices[2]->GetName(), "CON" ) == 0 )
  2122. + Devices[2]->SaveState(stream);
  2123. +}
  2124. +
  2125. +
  2126. +void POD_Load_DOS_Devices( std::istream& stream )
  2127. +{
  2128. + if( strcmp( Devices[2]->GetName(), "CON" ) == 0 )
  2129. + Devices[2]->LoadState(stream, false);
  2130. +}
  2131. \ No newline at end of file
  2132. Index: src/dos/dos_files.cpp
  2133. ===================================================================
  2134. --- src/dos/dos_files.cpp (revision 4176)
  2135. +++ src/dos/dos_files.cpp (working copy)
  2136. @@ -25,6 +25,9 @@
  2137. #include "dosbox.h"
  2138. #include "bios.h"
  2139. #include "mem.h"
  2140. +
  2141. +#include "../save_state.h"
  2142. +
  2143. #include "regs.h"
  2144. #include "dos_inc.h"
  2145. #include "drives.h"
  2146. @@ -1332,3 +1335,274 @@
  2147. }
  2148. Drives[25]=new Virtual_Drive();
  2149. }
  2150. +
  2151. +// save state support
  2152. +void DOS_File::SaveState( std::ostream& stream )
  2153. +{
  2154. + Bit32u file_namelen, seek_pos;
  2155. +
  2156. +
  2157. + file_namelen = strlen( name )+1;
  2158. + seek_pos = GetSeekPos();
  2159. +
  2160. + //******************************************
  2161. + //******************************************
  2162. + //******************************************
  2163. +
  2164. + // - pure data
  2165. + WRITE_POD( &file_namelen, file_namelen );
  2166. + WRITE_POD_SIZE( name, file_namelen );
  2167. +
  2168. + WRITE_POD( &flags, flags );
  2169. + WRITE_POD( &open, open );
  2170. +
  2171. + WRITE_POD( &attr, attr );
  2172. + WRITE_POD( &time, time );
  2173. + WRITE_POD( &date, date );
  2174. + WRITE_POD( &refCtr, refCtr );
  2175. + WRITE_POD( &hdrive, hdrive );
  2176. +
  2177. + //******************************************
  2178. + //******************************************
  2179. + //******************************************
  2180. +
  2181. + // - reloc ptr
  2182. + WRITE_POD( &seek_pos, seek_pos );
  2183. +}
  2184. +
  2185. +
  2186. +void DOS_File::LoadState( std::istream& stream, bool pop )
  2187. +{
  2188. + Bit32u file_namelen, seek_pos;
  2189. + char *file_name;
  2190. +
  2191. + //******************************************
  2192. + //******************************************
  2193. + //******************************************
  2194. +
  2195. + // - pure data
  2196. + READ_POD( &file_namelen, file_namelen );
  2197. + file_name = (char*)alloca( file_namelen * sizeof(char) );
  2198. + READ_POD_SIZE( file_name, file_namelen );
  2199. +
  2200. + READ_POD( &flags, flags );
  2201. + READ_POD( &open, open );
  2202. +
  2203. + READ_POD( &attr, attr );
  2204. + READ_POD( &time, time );
  2205. + READ_POD( &date, date );
  2206. + READ_POD( &refCtr, refCtr );
  2207. + READ_POD( &hdrive, hdrive );
  2208. +
  2209. + //******************************************
  2210. + //******************************************
  2211. + //******************************************
  2212. +
  2213. + // - reloc ptr
  2214. + READ_POD( &seek_pos, seek_pos );
  2215. +
  2216. + if (pop)
  2217. + return;
  2218. +
  2219. + if( open ) Seek( &seek_pos, DOS_SEEK_SET );
  2220. + else Close();
  2221. +}
  2222. +
  2223. +
  2224. +void POD_Save_DOS_Files( std::ostream& stream )
  2225. +{
  2226. + // 1. Do drives first (directories -> files)
  2227. + // 2. Then files next
  2228. +
  2229. + for( int lcv=0; lcv<DOS_DRIVES; lcv++ ) {
  2230. + Bit8u drive_valid;
  2231. +
  2232. +
  2233. + drive_valid = 0;
  2234. + if( Drives[lcv] == 0 ) drive_valid = 0xff;
  2235. +
  2236. + //**********************************************
  2237. + //**********************************************
  2238. + //**********************************************
  2239. +
  2240. + // - reloc ptr
  2241. + WRITE_POD( &drive_valid, drive_valid );
  2242. +
  2243. +
  2244. + if( drive_valid == 0xff ) continue;
  2245. + Drives[lcv]->SaveState(stream);
  2246. + }
  2247. +
  2248. +
  2249. + for( int lcv=0; lcv<DOS_FILES; lcv++ ) {
  2250. + Bit8u file_valid;
  2251. + char *file_name;
  2252. + Bit8u file_namelen, file_drive, file_flags;
  2253. +
  2254. +
  2255. + file_valid = 0;
  2256. + if( Files[lcv] == 0 ) file_valid = 0xff;
  2257. + else {
  2258. + if( strcmp( Files[lcv]->GetName(), "NUL" ) == 0 ) file_valid = 0xfe;//earth 2140 needs this
  2259. + if( strcmp( Files[lcv]->GetName(), "CON" ) == 0 ) file_valid = 0xfe;
  2260. + if( strcmp( Files[lcv]->GetName(), "LPT1" ) == 0 ) file_valid = 0xfe;
  2261. + if( strcmp( Files[lcv]->GetName(), "PRN" ) == 0 ) file_valid = 0xfe;
  2262. + if( strcmp( Files[lcv]->GetName(), "AUX" ) == 0 ) file_valid = 0xfe;
  2263. + if( strcmp( Files[lcv]->GetName(), "EMMXXXX0" ) == 0 ) file_valid = 0xfe;//raiden needs this
  2264. + }
  2265. +
  2266. +
  2267. + // - reloc ptr
  2268. + WRITE_POD( &file_valid, file_valid );
  2269. + // system files
  2270. + if( file_valid == 0xff ) continue;
  2271. + if( file_valid == 0xfe ) {
  2272. + WRITE_POD( &Files[lcv]->refCtr, Files[lcv]->refCtr );
  2273. + continue;
  2274. + }
  2275. +
  2276. + //**********************************************
  2277. + //**********************************************
  2278. + //**********************************************
  2279. +
  2280. + file_namelen = strlen( Files[lcv]->name ) + 1;
  2281. + file_name = (char *) alloca( file_namelen );
  2282. + strcpy( file_name, Files[lcv]->name );
  2283. +
  2284. + file_drive = Files[lcv]->GetDrive();
  2285. + file_flags = Files[lcv]->flags;
  2286. +
  2287. +
  2288. + // - Drives->FileOpen vars (repeat copy)
  2289. + WRITE_POD( &file_namelen, file_namelen );
  2290. + WRITE_POD_SIZE( file_name, file_namelen );
  2291. +
  2292. + WRITE_POD( &file_drive, file_drive );
  2293. + WRITE_POD( &file_flags, file_flags );
  2294. +
  2295. +
  2296. + Files[lcv]->SaveState(stream);
  2297. + }
  2298. +}
  2299. +
  2300. +
  2301. +void POD_Load_DOS_Files( std::istream& stream )
  2302. +{
  2303. + // 1. Do drives first (directories -> files)
  2304. + // 2. Then files next
  2305. +
  2306. + for( int lcv=0; lcv<DOS_DRIVES; lcv++ ) {
  2307. + Bit8u drive_valid;
  2308. +
  2309. + // - reloc ptr
  2310. + READ_POD( &drive_valid, drive_valid );
  2311. + if( drive_valid == 0xff ) continue;
  2312. +
  2313. +
  2314. + if( Drives[lcv] ) Drives[lcv]->LoadState(stream);
  2315. + }
  2316. +
  2317. + //Alien Carnage - game creates and unlinks temp files
  2318. + //Here are two situations
  2319. + //1. Game already unlinked temp file, but information about file is still in Files[] and we saved it. In this case we must only pop old data from stream by loading. This is fixed.
  2320. + //2. Game still did not unlink file, We saved this information. Then was game restarted and temp files were removed. Then we try load save state, but we don't have temp file. This is not fixed
  2321. + DOS_File *dummy = NULL;
  2322. +
  2323. + for( int lcv=0; lcv<DOS_FILES; lcv++ ) {
  2324. + Bit8u file_valid;
  2325. + char *file_name;
  2326. + Bit8u file_namelen, file_drive, file_flags;
  2327. +
  2328. + // - reloc ptr
  2329. + READ_POD( &file_valid, file_valid );
  2330. +
  2331. + // ignore system files
  2332. + if( file_valid == 0xfe ) {
  2333. + READ_POD( &Files[lcv]->refCtr, Files[lcv]->refCtr );
  2334. + continue;
  2335. + }
  2336. +
  2337. + // shutdown old file
  2338. + if( Files[lcv] ) {
  2339. + // invalid file state - abort
  2340. + if( strcmp( Files[lcv]->GetName(), "NUL" ) == 0 ) break;
  2341. + if( strcmp( Files[lcv]->GetName(), "CON" ) == 0 ) break;
  2342. + if( strcmp( Files[lcv]->GetName(), "LPT1" ) == 0 ) break;
  2343. + if( strcmp( Files[lcv]->GetName(), "PRN" ) == 0 ) break;
  2344. + if( strcmp( Files[lcv]->GetName(), "AUX" ) == 0 ) break;
  2345. + if( strcmp( Files[lcv]->GetName(), "EMMXXXX0" ) == 0 ) break;//raiden needs this
  2346. +
  2347. +
  2348. + if( Files[lcv]->IsOpen() ) Files[lcv]->Close();
  2349. + if (Files[lcv]->RemoveRef()<=0) {
  2350. + delete Files[lcv];
  2351. + }
  2352. + Files[lcv]=0;
  2353. + }
  2354. +
  2355. +
  2356. + // ignore NULL file
  2357. + if( file_valid == 0xff ) continue;
  2358. +
  2359. + //**********************************************
  2360. + //**********************************************
  2361. + //**********************************************
  2362. +
  2363. + // - Drives->FileOpen vars (repeat copy)
  2364. +
  2365. + READ_POD( &file_namelen, file_namelen );
  2366. + file_name = (char *) alloca( file_namelen );
  2367. + READ_POD_SIZE( file_name, file_namelen );
  2368. +
  2369. + READ_POD( &file_drive, file_drive );
  2370. + READ_POD( &file_flags, file_flags );
  2371. +
  2372. +
  2373. + // NOTE: Must open regardless to get 'new' DOS_File class
  2374. + Drives[file_drive]->FileOpen( &Files[lcv], file_name, file_flags );
  2375. +
  2376. + if( Files[lcv] ) {
  2377. + Files[lcv]->LoadState(stream, false);
  2378. + } else {
  2379. + //Alien carnage ->pop data for invalid file from stream
  2380. + if (dummy == NULL) {
  2381. + dummy = new localFile();
  2382. + }
  2383. + dummy->LoadState(stream, true);
  2384. + };
  2385. + }
  2386. +
  2387. + if (dummy != NULL) {
  2388. + delete dummy;
  2389. + }
  2390. +}
  2391. +
  2392. +/*
  2393. +ykhwong svn-daum 2012-02-20
  2394. +
  2395. +
  2396. +- reloc class 'new' data
  2397. +class DOS_File Files
  2398. + // - pure data (NULL warning)
  2399. + char* name;
  2400. +
  2401. + // - pure data
  2402. + Bit8u drive;
  2403. + Bit32u flags;
  2404. + bool open;
  2405. +
  2406. + Bit16u attr;
  2407. + Bit16u time;
  2408. + Bit16u date;
  2409. + Bits refCtr;
  2410. + bool newtime;
  2411. + Bit8u hdrive;
  2412. +
  2413. +
  2414. +
  2415. +- reloc class 'new' data
  2416. +class DOS_Drive *Drives[DOS_DRIVES];
  2417. + // - pure data
  2418. + char curdir[DOS_PATHLENGTH];
  2419. + char info[256];
  2420. +*/
  2421. Index: src/dos/dos_memory.cpp
  2422. ===================================================================
  2423. --- src/dos/dos_memory.cpp (revision 4176)
  2424. +++ src/dos/dos_memory.cpp (working copy)
  2425. @@ -20,6 +20,8 @@
  2426. #include "dosbox.h"
  2427. #include "mem.h"
  2428. #include "dos_inc.h"
  2429. +#include "callback.h"
  2430. +#include "../save_state.h"
  2431.  
  2432. #define UMB_START_SEG 0x9fff
  2433.  
  2434. @@ -446,3 +448,29 @@
  2435. dos.firstMCB=DOS_MEM_START;
  2436. dos_infoblock.SetFirstMCB(DOS_MEM_START);
  2437. }
  2438. +
  2439. +void POD_Save_DOS_Memory( std::ostream& stream )
  2440. +{
  2441. + // - pure data
  2442. + WRITE_POD( &memAllocStrategy, memAllocStrategy );
  2443. +}
  2444. +
  2445. +
  2446. +void POD_Load_DOS_Memory( std::istream& stream )
  2447. +{
  2448. + // - pure data
  2449. + READ_POD( &memAllocStrategy, memAllocStrategy );
  2450. +}
  2451. +
  2452. +
  2453. +/*
  2454. +ykhwong svn-daum 2012-05-21
  2455. +
  2456. +
  2457. +// - pure data
  2458. +static Bit16u memAllocStrategy;
  2459. +
  2460. +
  2461. +// - static class data
  2462. +static CALLBACK_HandlerObject callbackhandler;
  2463. +*/
  2464. Index: src/dos/dos_mscdex.cpp
  2465. ===================================================================
  2466. --- src/dos/dos_mscdex.cpp (revision 4176)
  2467. +++ src/dos/dos_mscdex.cpp (working copy)
  2468. @@ -30,6 +30,8 @@
  2469.  
  2470. #include "cdrom.h"
  2471.  
  2472. +#include "../save_state.h"
  2473. +
  2474. #define MSCDEX_LOG LOG(LOG_MISC,LOG_ERROR)
  2475. //#define MSCDEX_LOG
  2476.  
  2477. @@ -132,6 +134,9 @@
  2478. bool ResumeAudio (Bit8u subUnit);
  2479. bool GetMediaStatus (Bit8u subUnit, bool& media, bool& changed, bool& trayOpen);
  2480.  
  2481. + void SaveState( std::ostream& stream );
  2482. + void LoadState( std::istream& stream );
  2483. +
  2484. private:
  2485.  
  2486. PhysPt GetDefaultBuffer (void);
  2487. @@ -1350,3 +1355,151 @@
  2488. /* Create MSCDEX */
  2489. mscdex = new CMscdex;
  2490. }
  2491. +/**
  2492. +//save state support
  2493. +namespace
  2494. +{
  2495. +class SerializeCdrom : public SerializeGlobalPOD
  2496. +{
  2497. +public:
  2498. + SerializeCdrom() : SerializeGlobalPOD("Cdrom")
  2499. + {
  2500. + }
  2501. +
  2502. +private:
  2503. + virtual void getBytes(std::ostream& stream)
  2504. + {
  2505. + //writePOD(stream, xms_callback);
  2506. +
  2507. + SerializeGlobalPOD::getBytes(stream);
  2508. +
  2509. +
  2510. + for (Bit8u drive_unit=0; drive_unit<mscdex->GetNumDrives(); drive_unit++) {
  2511. + TMSF pos, start, end;
  2512. + bool playing, pause;
  2513. +
  2514. + mscdex->GetAudioStatus(drive_unit, playing, pause, start, end);
  2515. + mscdex->GetCurrentPos(drive_unit,pos);
  2516. +
  2517. + stream.write(reinterpret_cast<const char*>( &playing ), sizeof(playing) );
  2518. + stream.write(reinterpret_cast<const char*>( &pause ), sizeof(pause) );
  2519. + stream.write(reinterpret_cast<const char*>( &pos ), sizeof(pos) );
  2520. + stream.write(reinterpret_cast<const char*>( &start ), sizeof(start) );
  2521. + stream.write(reinterpret_cast<const char*>( &end ), sizeof(end) );
  2522. + }
  2523. + }
  2524. +
  2525. +
  2526. + virtual void setBytes(std::istream& stream)
  2527. + {
  2528. + //readPOD(stream, xms_callback);
  2529. +
  2530. +
  2531. + SerializeGlobalPOD::setBytes(stream);
  2532. +
  2533. +
  2534. + for (Bit8u drive_unit=0; drive_unit<mscdex->GetNumDrives(); drive_unit++) {
  2535. + TMSF pos, start, end;
  2536. + Bit32u msf_time, play_len;
  2537. + bool playing, pause;
  2538. +
  2539. +
  2540. +
  2541. + mscdex->StopAudio(drive_unit);
  2542. +
  2543. +
  2544. + stream.read(reinterpret_cast<char*>( &playing ), sizeof(playing) );
  2545. + stream.read(reinterpret_cast<char*>( &pause ), sizeof(pause) );
  2546. + stream.read(reinterpret_cast<char*>( &pos ), sizeof(pos) );
  2547. + stream.read(reinterpret_cast<char*>( &start ), sizeof(start) );
  2548. + stream.read(reinterpret_cast<char*>( &end ), sizeof(end) );
  2549. +
  2550. +
  2551. + msf_time = ( pos.min << 16 ) + ( pos.sec << 8 ) + ( pos.fr );
  2552. +
  2553. + // end = total play time (GetAudioStatus adds +150)
  2554. + // pos = current play cursor
  2555. + // start = start play cursor
  2556. + play_len = end.min * 75 * 60 + ( end.sec * 75 ) + end.fr - 150;
  2557. + play_len -= ( pos.min - start.min ) * 75 * 60 + ( pos.sec - start.sec ) * 75 + ( pos.fr - start.fr );
  2558. +
  2559. +
  2560. + // first play, then simulate pause
  2561. + if( playing ) mscdex->PlayAudioMSF(drive_unit, msf_time, play_len);
  2562. + if( pause ) mscdex->PlayAudioMSF(drive_unit, msf_time, 0);
  2563. + }
  2564. + }
  2565. +} dummy;
  2566. +}*/
  2567. +//save state support
  2568. +void CMscdex::SaveState( std::ostream& stream )
  2569. +{
  2570. + // - pure data
  2571. + WRITE_POD( &defaultBufSeg, defaultBufSeg );
  2572. + WRITE_POD( &rootDriverHeaderSeg, rootDriverHeaderSeg );
  2573. +}
  2574. +
  2575. +
  2576. +void CMscdex::LoadState( std::istream& stream )
  2577. +{
  2578. + // - pure data
  2579. + READ_POD( &defaultBufSeg, defaultBufSeg );
  2580. + READ_POD( &rootDriverHeaderSeg, rootDriverHeaderSeg );
  2581. +}
  2582. +
  2583. +
  2584. +void POD_Save_DOS_Mscdex( std::ostream& stream )
  2585. +{
  2586. + for (Bit8u drive_unit=0; drive_unit<mscdex->GetNumDrives(); drive_unit++) {
  2587. + TMSF pos, start, end;
  2588. + bool playing, pause;
  2589. +
  2590. + mscdex->GetAudioStatus(drive_unit, playing, pause, start, end);
  2591. + mscdex->GetCurrentPos(drive_unit,pos);
  2592. +
  2593. +
  2594. + WRITE_POD( &playing, playing );
  2595. + WRITE_POD( &pause, pause );
  2596. + WRITE_POD( &pos, pos );
  2597. + WRITE_POD( &start, start );
  2598. + WRITE_POD( &end, end );
  2599. + }
  2600. +
  2601. +
  2602. + mscdex->SaveState(stream);
  2603. +}
  2604. +
  2605. +
  2606. +void POD_Load_DOS_Mscdex( std::istream& stream )
  2607. +{
  2608. + for (Bit8u drive_unit=0; drive_unit<mscdex->GetNumDrives(); drive_unit++) {
  2609. + TMSF pos, start, end;
  2610. + Bit32u msf_time, play_len;
  2611. + bool playing, pause;
  2612. +
  2613. +
  2614. + READ_POD( &playing, playing );
  2615. + READ_POD( &pause, pause );
  2616. + READ_POD( &pos, pos );
  2617. + READ_POD( &start, start );
  2618. + READ_POD( &end, end );
  2619. +
  2620. +
  2621. + // end = total play time (GetAudioStatus adds +150)
  2622. + // pos = current play cursor
  2623. + // start = start play cursor
  2624. + play_len = end.min * 75 * 60 + ( end.sec * 75 ) + end.fr - 150;
  2625. + play_len -= ( pos.min - start.min ) * 75 * 60 + ( pos.sec - start.sec ) * 75 + ( pos.fr - start.fr );
  2626. + msf_time = ( pos.min << 16 ) + ( pos.sec << 8 ) + ( pos.fr );
  2627. +
  2628. +
  2629. + // first play, then simulate pause
  2630. + mscdex->StopAudio(drive_unit);
  2631. +
  2632. + if( playing ) mscdex->PlayAudioMSF(drive_unit, msf_time, play_len);
  2633. + if( pause ) mscdex->PlayAudioMSF(drive_unit, msf_time, 0);
  2634. + }
  2635. +
  2636. +
  2637. + mscdex->LoadState(stream);
  2638. +}
  2639. Index: src/dos/dos_tables.cpp
  2640. ===================================================================
  2641. --- src/dos/dos_tables.cpp (revision 4176)
  2642. +++ src/dos/dos_tables.cpp (working copy)
  2643. @@ -21,6 +21,7 @@
  2644. #include "mem.h"
  2645. #include "dos_inc.h"
  2646. #include "callback.h"
  2647. +#include "../save_state.h"
  2648.  
  2649. #ifdef _MSC_VER
  2650. #pragma pack(1)
  2651. @@ -177,3 +178,44 @@
  2652. host_writed(country_info + 0x12, CALLBACK_RealPointer(call_casemap));
  2653. dos.tables.country=country_info;
  2654. }
  2655. +
  2656. +// save state support
  2657. +void POD_Save_DOS_Tables( std::ostream& stream )
  2658. +{
  2659. + // - pure data
  2660. + WRITE_POD( &DOS_TableUpCase, DOS_TableUpCase );
  2661. + WRITE_POD( &DOS_TableLowCase, DOS_TableLowCase );
  2662. +
  2663. + WRITE_POD( &dos_memseg, dos_memseg );
  2664. +}
  2665. +
  2666. +
  2667. +void POD_Load_DOS_Tables( std::istream& stream )
  2668. +{
  2669. + // - pure data
  2670. + READ_POD( &DOS_TableUpCase, DOS_TableUpCase );
  2671. + READ_POD( &DOS_TableLowCase, DOS_TableLowCase );
  2672. +
  2673. + READ_POD( &dos_memseg, dos_memseg );
  2674. +}
  2675. +
  2676. +/*
  2677. +ykhwong svn-daum 2012-05-21
  2678. +
  2679. +
  2680. +// - pure data
  2681. +struct DOS_TableCase
  2682. + Bit16u size;
  2683. + Bit8u chars[256];
  2684. +
  2685. +RealPt DOS_TableUpCase;
  2686. +RealPt DOS_TableLowCase;
  2687. +
  2688. +
  2689. +// - assume static func ptr
  2690. +static Bitu call_casemap;
  2691. +
  2692. +
  2693. +// - pure data
  2694. +static Bit16u dos_memseg;
  2695. +*/
  2696. \ No newline at end of file
  2697. Index: src/dos/drive_fat.cpp
  2698. ===================================================================
  2699. --- src/dos/drive_fat.cpp (revision 4176)
  2700. +++ src/dos/drive_fat.cpp (working copy)
  2701. @@ -46,6 +46,9 @@
  2702. bool Close();
  2703. Bit16u GetInformation(void);
  2704. bool UpdateDateTimeFromHost(void);
  2705. +
  2706. + Bit32u GetSeekPos(void);
  2707. +
  2708. public:
  2709. Bit32u firstCluster;
  2710. Bit32u seekpos;
  2711. @@ -299,6 +302,10 @@
  2712. return true;
  2713. }
  2714.  
  2715. +Bit32u fatFile::GetSeekPos() {
  2716. + return seekpos;
  2717. +}
  2718. +
  2719. Bit32u fatDrive::getClustFirstSect(Bit32u clustNum) {
  2720. return ((clustNum - 2) * bootbuffer.sectorspercluster) + firstDataSector;
  2721. }
  2722. Index: src/dos/drive_iso.cpp
  2723. ===================================================================
  2724. --- src/dos/drive_iso.cpp (revision 4176)
  2725. +++ src/dos/drive_iso.cpp (working copy)
  2726. @@ -38,6 +38,9 @@
  2727. bool Seek(Bit32u *pos, Bit32u type);
  2728. bool Close();
  2729. Bit16u GetInformation(void);
  2730. +
  2731. + Bit32u GetSeekPos(void);
  2732. +
  2733. private:
  2734. isoDrive *drive;
  2735. Bit8u buffer[ISO_FRAMESIZE];
  2736. @@ -133,6 +136,10 @@
  2737. return 0x40; // read-only drive
  2738. }
  2739.  
  2740. +Bit32u isoFile::GetSeekPos() {
  2741. + return filePos - fileBegin;
  2742. +}
  2743. +
  2744. int MSCDEX_RemoveDrive(char driveLetter);
  2745. int MSCDEX_AddDrive(char driveLetter, const char* physicalPath, Bit8u& subUnit);
  2746. void MSCDEX_ReplaceDrive(CDROM_Interface* cdrom, Bit8u subUnit);
  2747. Index: src/dos/drive_local.cpp
  2748. ===================================================================
  2749. --- src/dos/drive_local.cpp (revision 4176)
  2750. +++ src/dos/drive_local.cpp (working copy)
  2751. @@ -507,7 +507,11 @@
  2752. return read_only_medium?0x40:0;
  2753. }
  2754.  
  2755. +Bit32u localFile::GetSeekPos() {
  2756. + return ftell( fhandle );
  2757. +}
  2758.  
  2759. +localFile::localFile() {}
  2760. localFile::localFile(const char* _name, FILE * handle) {
  2761. fhandle=handle;
  2762. open=true;
  2763. Index: src/dos/drives.cpp
  2764. ===================================================================
  2765. --- src/dos/drives.cpp (revision 4176)
  2766. +++ src/dos/drives.cpp (working copy)
  2767. @@ -23,6 +23,8 @@
  2768. #include "mapper.h"
  2769. #include "support.h"
  2770.  
  2771. +#include "../save_state.h"
  2772. +
  2773. bool WildFileCmp(const char * file, const char * wild)
  2774. {
  2775. char file_name[9];
  2776. @@ -228,3 +230,45 @@
  2777. void DRIVES_Init(Section* sec) {
  2778. DriveManager::Init(sec);
  2779. }
  2780. +
  2781. +// save state support
  2782. +void DOS_Drive::SaveState( std::ostream& stream )
  2783. +{
  2784. + // - pure data
  2785. + WRITE_POD( &curdir, curdir );
  2786. + WRITE_POD( &info, info );
  2787. +}
  2788. +
  2789. +
  2790. +void DOS_Drive::LoadState( std::istream& stream )
  2791. +{
  2792. + // - pure data
  2793. + READ_POD( &curdir, curdir );
  2794. + READ_POD( &info, info );
  2795. +}
  2796. +
  2797. +
  2798. +void DriveManager::SaveState( std::ostream& stream )
  2799. +{
  2800. + // - pure data
  2801. + WRITE_POD( &currentDrive, currentDrive );
  2802. +}
  2803. +
  2804. +
  2805. +void DriveManager::LoadState( std::istream& stream )
  2806. +{
  2807. + // - pure data
  2808. + READ_POD( &currentDrive, currentDrive );
  2809. +}
  2810. +
  2811. +
  2812. +void POD_Save_DOS_DriveManager( std::ostream& stream )
  2813. +{
  2814. + DriveManager::SaveState(stream);
  2815. +}
  2816. +
  2817. +
  2818. +void POD_Load_DOS_DriveManager( std::istream& stream )
  2819. +{
  2820. + DriveManager::LoadState(stream);
  2821. +}
  2822. \ No newline at end of file
  2823. Index: src/dos/drives.h
  2824. ===================================================================
  2825. --- src/dos/drives.h (revision 4176)
  2826. +++ src/dos/drives.h (working copy)
  2827. @@ -39,6 +39,9 @@
  2828. static void CycleAllDisks(void);
  2829. static void Init(Section* sec);
  2830.  
  2831. + static void SaveState( std::ostream& stream );
  2832. + static void LoadState( std::istream& stream );
  2833. +
  2834. private:
  2835. static struct DriveInfo {
  2836. std::vector<DOS_Drive*> disks;
  2837. Index: src/dosbox.cpp
  2838. ===================================================================
  2839. --- src/dosbox.cpp (revision 4176)
  2840. +++ src/dosbox.cpp (working copy)
  2841. @@ -22,6 +22,9 @@
  2842. #include <stdio.h>
  2843. #include <string.h>
  2844. #include <unistd.h>
  2845. +
  2846. +#include <ctime>
  2847. +
  2848. #include "dosbox.h"
  2849. #include "debug.h"
  2850. #include "cpu.h"
  2851. @@ -43,6 +46,8 @@
  2852. #include "render.h"
  2853. #include "pci_bus.h"
  2854.  
  2855. +#include "save_state.h"
  2856. +
  2857. Config * control;
  2858. MachineType machine;
  2859. SVGACards svgaCard;
  2860. @@ -342,6 +347,125 @@
  2861. }
  2862. }
  2863.  
  2864. +static void DOSBOX_UnlockSpeed2( bool pressed ) {
  2865. + if (pressed) {
  2866. + ticksLocked =! ticksLocked;
  2867. + DOSBOX_UnlockSpeed(ticksLocked?true:false);
  2868. + }
  2869. +}
  2870. +
  2871. +namespace
  2872. +{
  2873. +std::string getTime()
  2874. +{
  2875. + const time_t current = time(NULL);
  2876. + tm* timeinfo;
  2877. + timeinfo = localtime(&current); //convert to local time
  2878. + char buffer[50];
  2879. + ::strftime(buffer, 50, "%H:%M:%S", timeinfo);
  2880. + return buffer;
  2881. +}
  2882. +
  2883. +class SlotPos
  2884. +{
  2885. +public:
  2886. + SlotPos() : slot(0) {}
  2887. +
  2888. + void next()
  2889. + {
  2890. + ++slot;
  2891. + slot %= SaveState::SLOT_COUNT;
  2892. + }
  2893. +
  2894. + void previous()
  2895. + {
  2896. + slot += SaveState::SLOT_COUNT - 1;
  2897. + slot %= SaveState::SLOT_COUNT;
  2898. + }
  2899. +
  2900. + void set(int value)
  2901. + {
  2902. + slot = value;
  2903. + }
  2904. +
  2905. + operator size_t() const
  2906. + {
  2907. + return slot;
  2908. + }
  2909. +private:
  2910. + size_t slot;
  2911. +} currentSlot;
  2912. +
  2913. +void notifyError(const std::string& message)
  2914. +{
  2915. +#ifdef WIN32
  2916. + ::MessageBox(0, message.c_str(), "Error", 0);
  2917. +#endif
  2918. + LOG_MSG(message.c_str());
  2919. +}
  2920. +
  2921. +void SetGameState(int value) {
  2922. + currentSlot.set(value);
  2923. +}
  2924. +
  2925. +void SaveGameState(bool pressed) {
  2926. + if (!pressed) return;
  2927. +
  2928. + try
  2929. + {
  2930. + SaveState::instance().save(currentSlot);
  2931. + LOG_MSG("[%s]: State %d saved!", getTime().c_str(), currentSlot + 1);
  2932. + }
  2933. + catch (const SaveState::Error& err)
  2934. + {
  2935. + notifyError(err);
  2936. + }
  2937. +}
  2938. +
  2939. +void LoadGameState(bool pressed) {
  2940. + if (!pressed) return;
  2941. +
  2942. +// if (SaveState::instance().isEmpty(currentSlot))
  2943. +// {
  2944. +// LOG_MSG("[%s]: State %d is empty!", getTime().c_str(), currentSlot + 1);
  2945. +// return;
  2946. +// }
  2947. + try
  2948. + {
  2949. + SaveState::instance().load(currentSlot);
  2950. + LOG_MSG("[%s]: State %d loaded!", getTime().c_str(), currentSlot + 1);
  2951. + }
  2952. + catch (const SaveState::Error& err)
  2953. + {
  2954. + notifyError(err);
  2955. + }
  2956. +}
  2957. +
  2958. +void NextSaveSlot(bool pressed) {
  2959. + if (!pressed) return;
  2960. +
  2961. + currentSlot.next();
  2962. +
  2963. + const bool emptySlot = SaveState::instance().isEmpty(currentSlot);
  2964. + LOG_MSG("Active save slot: %d %s", currentSlot + 1, emptySlot ? "[Empty]" : "");
  2965. +}
  2966. +
  2967. +
  2968. +void PreviousSaveSlot(bool pressed) {
  2969. + if (!pressed) return;
  2970. +
  2971. + currentSlot.previous();
  2972. +
  2973. + const bool emptySlot = SaveState::instance().isEmpty(currentSlot);
  2974. + LOG_MSG("Active save slot: %d %s", currentSlot + 1, emptySlot ? "[Empty]" : "");
  2975. +}
  2976. +}
  2977. +void SetGameState_Run(int value) { SetGameState(value); }
  2978. +void SaveGameState_Run(void) { SaveGameState(true); }
  2979. +void LoadGameState_Run(void) { LoadGameState(true); }
  2980. +void NextSaveSlot_Run(void) { NextSaveSlot(true); }
  2981. +void PreviousSaveSlot_Run(void) { PreviousSaveSlot(true); }
  2982. +
  2983. static void DOSBOX_RealInit(Section * sec) {
  2984. Section_prop * section=static_cast<Section_prop *>(sec);
  2985. /* Initialize some dosbox internals */
  2986. @@ -353,6 +477,9 @@
  2987. MSG_Init(section);
  2988.  
  2989. MAPPER_AddHandler(DOSBOX_UnlockSpeed, MK_f12, MMOD2,"speedlock","Speedlock");
  2990. +
  2991. + MAPPER_AddHandler(DOSBOX_UnlockSpeed2, MK_f12, MMOD1|MMOD2,"speedlock2","Speedlock2");
  2992. +
  2993. std::string cmd_machine;
  2994. if (control->cmdline->FindString("-machine",cmd_machine,true)){
  2995. //update value in config (else no matching against suggested values
  2996. @@ -359,7 +486,13 @@
  2997. section->HandleInputline(std::string("machine=") + cmd_machine);
  2998. }
  2999.  
  3000. - std::string mtype(section->Get_string("machine"));
  3001. + //add support for loading/saving game states
  3002. + MAPPER_AddHandler(SaveGameState, MK_f5, MMOD2,"savestate","Save State");
  3003. + MAPPER_AddHandler(LoadGameState, MK_f9, MMOD2,"loadstate","Load State");
  3004. + MAPPER_AddHandler(PreviousSaveSlot, MK_f6, MMOD2,"prevslot","Prev. Slot");
  3005. + MAPPER_AddHandler(NextSaveSlot, MK_f7, MMOD2,"nextslot","Next Slot");
  3006. +
  3007. + std::string mtype(section->Get_string("machine"));
  3008. svgaCard = SVGA_None;
  3009. machine = MCH_VGA;
  3010. int10.vesa_nolfb = false;
  3011. @@ -791,3 +924,62 @@
  3012.  
  3013. control->SetStartUp(&SHELL_Init);
  3014. }
  3015. +
  3016. +extern void POD_Save_Sdlmain( std::ostream& stream );
  3017. +extern void POD_Load_Sdlmain( std::istream& stream );
  3018. +
  3019. +// save state support
  3020. +
  3021. +namespace
  3022. +{
  3023. +class SerializeDosbox : public SerializeGlobalPOD
  3024. +{
  3025. +public:
  3026. + SerializeDosbox() : SerializeGlobalPOD("Dosbox")
  3027. + {}
  3028. +
  3029. +private:
  3030. + virtual void getBytes(std::ostream& stream)
  3031. + {
  3032. +
  3033. + //******************************************
  3034. + //******************************************
  3035. + //******************************************
  3036. +
  3037. + SerializeGlobalPOD::getBytes(stream);
  3038. +
  3039. + //******************************************
  3040. + //******************************************
  3041. + //******************************************
  3042. +
  3043. + POD_Save_Sdlmain(stream);
  3044. + }
  3045. +
  3046. + virtual void setBytes(std::istream& stream)
  3047. + {
  3048. +
  3049. + //******************************************
  3050. + //******************************************
  3051. + //******************************************
  3052. +
  3053. + SerializeGlobalPOD::setBytes(stream);
  3054. +
  3055. + //******************************************
  3056. + //******************************************
  3057. + //******************************************
  3058. +
  3059. + POD_Load_Sdlmain(stream);
  3060. +
  3061. + //*******************************************
  3062. + //*******************************************
  3063. + //*******************************************
  3064. +
  3065. + // Reset any auto cycle guessing for this frame
  3066. + ticksRemain=5;
  3067. + ticksLast = GetTicks();
  3068. + ticksAdded = 0;
  3069. + ticksDone = 0;
  3070. + ticksScheduled = 0;
  3071. + }
  3072. +} dummy;
  3073. +}
  3074. \ No newline at end of file
  3075. Index: src/fpu/fpu.cpp
  3076. ===================================================================
  3077. --- src/fpu/fpu.cpp (revision 4176)
  3078. +++ src/fpu/fpu.cpp (working copy)
  3079. @@ -27,6 +27,8 @@
  3080. #include "fpu.h"
  3081. #include "cpu.h"
  3082.  
  3083. +#include "../save_state.h"
  3084. +
  3085. FPU_rec fpu;
  3086.  
  3087. void FPU_FLDCW(PhysPt addr){
  3088. @@ -628,3 +630,16 @@
  3089. }
  3090.  
  3091. #endif
  3092. +
  3093. +//save state support
  3094. +namespace
  3095. +{
  3096. +class SerializeFpu : public SerializeGlobalPOD
  3097. +{
  3098. +public:
  3099. + SerializeFpu() : SerializeGlobalPOD("FPU")
  3100. + {
  3101. + registerPOD(fpu);
  3102. + }
  3103. +} dummy;
  3104. +}
  3105. \ No newline at end of file
  3106. Index: src/gui/midi.cpp
  3107. ===================================================================
  3108. --- src/gui/midi.cpp (revision 4176)
  3109. +++ src/gui/midi.cpp (working copy)
  3110. @@ -34,6 +34,8 @@
  3111. #include "hardware.h"
  3112. #include "timer.h"
  3113.  
  3114. +#include "../save_state.h"
  3115. +
  3116. #define RAWBUF 1024
  3117.  
  3118. Bit8u MIDI_evt_len[256] = {
  3119. @@ -68,6 +70,24 @@
  3120.  
  3121. MidiHandler Midi_none;
  3122.  
  3123. +static struct {
  3124. + bool init;
  3125. + bool ignore;
  3126. +
  3127. + // NOTE: 16-bit ($ffff = not used, $00-ff = data value)
  3128. + Bit16u code_80[0x80]; // note off (w/ velocity)
  3129. + Bit16u code_90[0x80]; // note on (w/ velocity)
  3130. + Bit16u code_a0[0x80]; // aftertouch (polyphonic key pressure)
  3131. + Bit16u code_b0[0x80]; // Continuous controller (GM 1.0 + GS)
  3132. + Bit16u code_c0[1]; // patch change
  3133. + Bit16u code_d0[1]; // channel pressure (after-touch)
  3134. + Bit16u code_e0[2]; // pitch bend
  3135. + //Bit16u code_f0-ff // system messages
  3136. +
  3137. + Bit16u code_rpn_coarse[3]; // registered parameter numbers (GM 1.0)
  3138. + Bit16u code_rpn_fine[3]; // registered parameter numbers (GM 1.0)
  3139. +} midi_state[16];
  3140. +
  3141. /* Include different midi drivers, lowest ones get checked first for default */
  3142.  
  3143. #if defined(MACOSX)
  3144. @@ -93,6 +113,424 @@
  3145.  
  3146. DB_Midi midi;
  3147.  
  3148. +//#define WIN32_MIDI_STATE_DEBUG
  3149. +
  3150. +void MIDI_State_Reset()
  3151. +{
  3152. + memset( &midi_state, 0xff, sizeof(midi_state) );
  3153. +
  3154. + midi_state[0].init = true;
  3155. + midi_state[0].ignore = false;
  3156. +}
  3157. +
  3158. +
  3159. +void MIDI_State_SaveMessage()
  3160. +{
  3161. + Bit8u channel, command, arg1, arg2;
  3162. +
  3163. + if( midi_state[0].init == false ) {
  3164. + MIDI_State_Reset();
  3165. + }
  3166. +
  3167. + if( midi_state[0].ignore == true ) return;
  3168. +
  3169. +
  3170. + channel = midi.cmd_buf[0] & 0xf;
  3171. + command = midi.cmd_buf[0] >> 4;
  3172. + arg1 = midi.cmd_buf[1];
  3173. + arg2 = midi.cmd_buf[2];
  3174. +
  3175. + switch( command ) {
  3176. + case 0x8: // Note off
  3177. + // - arg1 = note, arg2 = velocity off
  3178. + midi_state[channel].code_80[arg1] = arg2;
  3179. +
  3180. + memset( &midi_state[channel].code_90[arg1], 0xff, sizeof(midi_state[channel].code_90[arg1]) );
  3181. + memset( &midi_state[channel].code_a0[arg1], 0xff, sizeof(midi_state[channel].code_a0[arg1]) );
  3182. + memset( midi_state[channel].code_d0, 0xff, sizeof(midi_state[channel].code_d0) );
  3183. + break;
  3184. +
  3185. +
  3186. + case 0x9: // Note on
  3187. + if( arg2 > 0 ) {
  3188. + // - arg1 = note, arg2 = velocity on
  3189. + midi_state[channel].code_90[arg1] = arg2;
  3190. +
  3191. + memset( &midi_state[channel].code_80[arg1], 0xff, sizeof(midi_state[channel].code_80[arg1]) );
  3192. + }
  3193. + else {
  3194. + // velocity = 0 (note off)
  3195. + midi_state[channel].code_80[arg1] = arg2;
  3196. +
  3197. + memset( &midi_state[channel].code_90[arg1], 0xff, sizeof(midi_state[channel].code_90[arg1]) );
  3198. + memset( &midi_state[channel].code_a0[arg1], 0xff, sizeof(midi_state[channel].code_a0[arg1]) );
  3199. + memset( midi_state[channel].code_d0, 0xff, sizeof(midi_state[channel].code_d0) );
  3200. + }
  3201. + break;
  3202. +
  3203. +
  3204. + case 0xA: // Aftertouch (polyphonic pressure)
  3205. + midi_state[channel].code_a0[arg1] = arg2;
  3206. + break;
  3207. +
  3208. +
  3209. + case 0xB: // Controller #s
  3210. + midi_state[channel].code_b0[arg1] = arg2;
  3211. +
  3212. + switch( arg1 ) {
  3213. + // General Midi 1.0
  3214. + case 0x01: break; // Modulation
  3215. +
  3216. + case 0x07: break; // Volume
  3217. + case 0x0A: break; // Pan
  3218. + case 0x0B: break; // Expression
  3219. +
  3220. + case 0x40: break; // Sustain pedal
  3221. +
  3222. + case 0x64: break; // Registered Parameter Number (RPN) LSB
  3223. + case 0x65: break; // Registered Parameter Number (RPN) MSB
  3224. +
  3225. + case 0x79: // All controllers off
  3226. + /*
  3227. + (likely GM1+GM2)
  3228. + Set Expression (#11) to 127
  3229. + Set Modulation (#1) to 0
  3230. + Set Pedals (#64, #65, #66, #67) to 0
  3231. + Set Registered and Non-registered parameter number LSB and MSB (#98-#101) to null value (127)
  3232. + Set pitch bender to center (64/0)
  3233. + Reset channel pressure to 0
  3234. + Reset polyphonic pressure for all notes to 0.
  3235. + */
  3236. + memset( midi_state[channel].code_a0, 0xff, sizeof(midi_state[channel].code_a0) );
  3237. + memset( midi_state[channel].code_c0, 0xff, sizeof(midi_state[channel].code_c0) );
  3238. + memset( midi_state[channel].code_d0, 0xff, sizeof(midi_state[channel].code_d0) );
  3239. + memset( midi_state[channel].code_e0, 0xff, sizeof(midi_state[channel].code_e0) );
  3240. +
  3241. + memset( midi_state[channel].code_b0+0x01, 0xff, sizeof(midi_state[channel].code_b0[0x01]) );
  3242. + memset( midi_state[channel].code_b0+0x0b, 0xff, sizeof(midi_state[channel].code_b0[0x0b]) );
  3243. + memset( midi_state[channel].code_b0+0x40, 0xff, sizeof(midi_state[channel].code_b0[0x40]) );
  3244. +
  3245. + memset( midi_state[channel].code_rpn_coarse, 0xff, sizeof(midi_state[channel].code_rpn_coarse) );
  3246. + memset( midi_state[channel].code_rpn_fine, 0xff, sizeof(midi_state[channel].code_rpn_fine) );
  3247. +
  3248. + /*
  3249. + (likely GM1+GM2)
  3250. + Do NOT reset Bank Select (#0/#32)
  3251. + Do NOT reset Volume (#7)
  3252. + Do NOT reset Pan (#10)
  3253. + Do NOT reset Program Change
  3254. + Do NOT reset Effect Controllers (#91-#95) (5B-5F)
  3255. + Do NOT reset Sound Controllers (#70-#79) (46-4F)
  3256. + Do NOT reset other channel mode messages (#120-#127) (78-7F)
  3257. + Do NOT reset registered or non-registered parameters.
  3258. + */
  3259. + //Intentional fall-through
  3260. +
  3261. + case 0x7b: // All notes off
  3262. + memset( midi_state[channel].code_80, 0xff, sizeof(midi_state[channel].code_80) );
  3263. + memset( midi_state[channel].code_90, 0xff, sizeof(midi_state[channel].code_90) );
  3264. + break;
  3265. +
  3266. + //******************************************
  3267. + //******************************************
  3268. + //******************************************
  3269. +
  3270. + // Roland GS
  3271. + case 0x00: break; // Bank select MSB
  3272. + case 0x05: break; // Portamento time
  3273. + case 0x20: break; // Bank select LSB
  3274. + case 0x41: break; // Portamento
  3275. + case 0x42: break; // Sostenuto
  3276. + case 0x43: break; // Soft pedal
  3277. + case 0x54: break; // Portamento control
  3278. + case 0x5B: break; // Effect 1 (Reverb) send level
  3279. + case 0x5D: break; // Effect 3 (Chorus) send level
  3280. + case 0x5E: break; // Effect 4 (Variation) send level
  3281. +
  3282. + // TODO: Add more as needed
  3283. + case 0x62: // NRPN LSB
  3284. +#ifdef WIN32_MIDI_STATE_DEBUG
  3285. + {
  3286. + char str[512];
  3287. +
  3288. + sprintf( str, "GS NRPN %x = %x", arg1, arg2 );
  3289. + MessageBox( 0, str, "MIDI State", 0 );
  3290. + }
  3291. +#endif
  3292. + break;
  3293. + //case 0x63: break; // NRPN MSB
  3294. + //case 0x78: break; // All sounds off (TODO)
  3295. +
  3296. +
  3297. + /*
  3298. + // Roland MT-32
  3299. + case 0x64:
  3300. + parts[part]->setRPNLSB(velocity);
  3301. + break;
  3302. + case 0x65:
  3303. + parts[part]->setRPNMSB(velocity);
  3304. + break;
  3305. +
  3306. + case 0x7B: // All notes off
  3307. + //printDebug("All notes off");
  3308. + parts[part]->allNotesOff();
  3309. + break;
  3310. +
  3311. + case 0x7C:
  3312. + case 0x7D:
  3313. + case 0x7E:
  3314. + case 0x7F:
  3315. + // CONFIRMED:Mok: A real LAPC-I responds to these controllers as follows:
  3316. + parts[part]->setHoldPedal(false);
  3317. + parts[part]->allNotesOff();
  3318. + break;
  3319. + */
  3320. +
  3321. + //******************************************
  3322. + //******************************************
  3323. + //******************************************
  3324. +
  3325. + /*
  3326. + (LSB,MSB) RPN
  3327. +
  3328. + GM 1.0
  3329. + 00,00 = Pitch bend range (fine + coarse)
  3330. + 01,00 = Channel Fine tuning
  3331. + 02,00 = Channel Coarse tuning
  3332. + 7F,7F = None
  3333. + */
  3334. +
  3335. + case 0x06: // Data entry (coarse)
  3336. + {
  3337. + int rpn;
  3338. +
  3339. + rpn = midi_state[channel].code_b0[0x64];
  3340. + rpn |= (midi_state[channel].code_b0[0x65]) << 8;
  3341. +
  3342. +
  3343. + // GM 1.0 = 0-2
  3344. + if( rpn >= 3 ) {
  3345. +#ifdef WIN32_MIDI_STATE_DEBUG
  3346. + char str[512];
  3347. +
  3348. + sprintf( str, "RPN coarse %x = %x", rpn, arg2 );
  3349. + MessageBox( 0, str, "MIDI State", 0 );
  3350. +#endif
  3351. + break;
  3352. + }
  3353. + if( rpn == 0x7f7f ) break;
  3354. +
  3355. + midi_state[channel].code_rpn_coarse[rpn] = arg2;
  3356. + }
  3357. + break;
  3358. +
  3359. +
  3360. + case 0x26: // Data entry (fine)
  3361. + {
  3362. + int rpn;
  3363. +
  3364. + rpn = midi_state[channel].code_b0[0x64];
  3365. + rpn |= (midi_state[channel].code_b0[0x65]) << 8;
  3366. +
  3367. +
  3368. + // GM 1.0 = 0-2
  3369. + if( rpn >= 3 ) {
  3370. +#ifdef WIN32_MIDI_STATE_DEBUG
  3371. + char str[512];
  3372. +
  3373. + sprintf( str, "RPN fine %x = %x", rpn, arg2 );
  3374. + MessageBox( 0, str, "MIDI State", 0 );
  3375. +#endif
  3376. + break;
  3377. + }
  3378. + if( rpn == 0x7f7f ) break;
  3379. +
  3380. + midi_state[channel].code_rpn_fine[rpn] = arg2;
  3381. + }
  3382. + break;
  3383. +
  3384. +
  3385. + default: // unsupported
  3386. +#ifdef WIN32_MIDI_STATE_DEBUG
  3387. + {
  3388. + char str[512];
  3389. +
  3390. + // Ignore 'illegal' modes for now
  3391. + if( arg1 != 0x70 && arg1 != 0x72 ) {
  3392. + sprintf( str, "Control %x = %x", arg1, arg2 );
  3393. + //MessageBox( 0, str, "MIDI State", 0 );
  3394. + }
  3395. + }
  3396. +#endif
  3397. +
  3398. + //__asm int 3
  3399. + break;
  3400. + }
  3401. + break;
  3402. +
  3403. +
  3404. + case 0xC: // Patch change
  3405. + midi_state[channel].code_c0[0] = arg1;
  3406. + break;
  3407. +
  3408. + case 0xD: // Channel pressure (aftertouch)
  3409. + midi_state[channel].code_d0[0] = arg1;
  3410. + break;
  3411. +
  3412. + case 0xE: // Pitch bend
  3413. + midi_state[channel].code_e0[0] = arg1;
  3414. + midi_state[channel].code_e0[1] = arg2;
  3415. + break;
  3416. +
  3417. + case 0xF: // System messages
  3418. + // TODO: General Midi 1.0 says 'Master Volume' SysEx
  3419. + break;
  3420. +
  3421. + // unhandled case
  3422. + default:
  3423. + break;
  3424. + }
  3425. +}
  3426. +
  3427. +
  3428. +void MIDI_RawOutByte(Bit8u);
  3429. +void MIDI_State_LoadMessage()
  3430. +{
  3431. + if( midi_state[0].init == false ) {
  3432. + MIDI_State_Reset();
  3433. + }
  3434. +
  3435. +
  3436. + // flush data buffer
  3437. + if( midi.status < 0xf0 ) {
  3438. + // throw invalid midi message - start new cmd
  3439. + MIDI_RawOutByte(0x80);
  3440. + }
  3441. + else if( midi.status == 0xf0 ) {
  3442. + // SysEx - throw invalid midi message
  3443. + MIDI_RawOutByte(0xf7);
  3444. + }
  3445. +
  3446. +
  3447. + midi_state[0].ignore = true;
  3448. +
  3449. + // shutdown sound
  3450. + for( int lcv=0; lcv<16; lcv++ ) {
  3451. + MIDI_RawOutByte( 0xb0+lcv );
  3452. + MIDI_RawOutByte( 0x78 );
  3453. + MIDI_RawOutByte( 0x00 );
  3454. +
  3455. + MIDI_RawOutByte( 0x79 );
  3456. + MIDI_RawOutByte( 0x00 );
  3457. +
  3458. + // GS-way
  3459. + MIDI_RawOutByte( 0x7b );
  3460. + MIDI_RawOutByte( 0x00 );
  3461. + }
  3462. +
  3463. +
  3464. + for( int lcv=0; lcv<16; lcv++ ) {
  3465. + // control states (bx - 00-5F)
  3466. + MIDI_RawOutByte( 0xb0+lcv );
  3467. +
  3468. +
  3469. + for( int lcv2=0; lcv2<0x80; lcv2++ ) {
  3470. + if( lcv2 >= 0x60 ) break;
  3471. + if( midi_state[lcv].code_b0[lcv2] == 0xffff ) continue;
  3472. +
  3473. + // RPN data - coarse / fine
  3474. + if( lcv2 == 0x06 ) continue;
  3475. + if( lcv2 == 0x26 ) continue;
  3476. +
  3477. +
  3478. + //MIDI_RawOutByte( 0xb0+lcv );
  3479. + MIDI_RawOutByte( lcv2 );
  3480. + MIDI_RawOutByte( midi_state[lcv].code_b0[lcv2] & 0xff );
  3481. + }
  3482. +
  3483. +
  3484. + // control states - RPN data (GM 1.0)
  3485. + for( int lcv2=0; lcv2<3; lcv2++ ) {
  3486. + if( midi_state[lcv].code_rpn_coarse[lcv2] == 0xffff &&
  3487. + midi_state[lcv].code_rpn_fine[lcv2] == 0xffff ) continue;
  3488. +
  3489. +
  3490. + //MIDI_RawOutByte( 0xb0+lcv );
  3491. + MIDI_RawOutByte( 0x64 );
  3492. + MIDI_RawOutByte( lcv2 );
  3493. + MIDI_RawOutByte( 0x65 );
  3494. + MIDI_RawOutByte( 0x00 );
  3495. +
  3496. +
  3497. + //MIDI_RawOutByte( 0xb0+lcv );
  3498. + MIDI_RawOutByte( 0x06 );
  3499. + MIDI_RawOutByte( midi_state[lcv].code_rpn_coarse[lcv2] & 0xff );
  3500. + MIDI_RawOutByte( 0x26 );
  3501. + MIDI_RawOutByte( midi_state[lcv].code_rpn_fine[lcv2] & 0xff );
  3502. +
  3503. +
  3504. + //MIDI_RawOutByte( 0xb0+lcv );
  3505. + MIDI_RawOutByte( 0x64 );
  3506. + MIDI_RawOutByte( 0x7f );
  3507. + MIDI_RawOutByte( 0x65 );
  3508. + MIDI_RawOutByte( 0x7f );
  3509. + }
  3510. +
  3511. +
  3512. + // program change
  3513. + if( midi_state[lcv].code_c0[0] != 0xffff ) {
  3514. + MIDI_RawOutByte( 0xc0+lcv );
  3515. + MIDI_RawOutByte( midi_state[lcv].code_c0[0]&0xff );
  3516. + }
  3517. +
  3518. +
  3519. + // pitch wheel change
  3520. + if( midi_state[lcv].code_e0[0] != 0xffff ) {
  3521. + MIDI_RawOutByte( 0xe0+lcv );
  3522. + MIDI_RawOutByte( midi_state[lcv].code_e0[0]&0xff );
  3523. + MIDI_RawOutByte( midi_state[lcv].code_e0[1]&0xff );
  3524. + }
  3525. +
  3526. + //******************************************
  3527. + //******************************************
  3528. + //******************************************
  3529. +
  3530. + // note on
  3531. + MIDI_RawOutByte( 0x90+lcv );
  3532. +
  3533. + for( int lcv2=0; lcv2<0x80; lcv2++ ) {
  3534. + if( midi_state[lcv].code_90[lcv2] == 0xffff ) continue;
  3535. +
  3536. +
  3537. + //MIDI_RawOutByte( 0x90+lcv );
  3538. + MIDI_RawOutByte( lcv2 );
  3539. + MIDI_RawOutByte( midi_state[lcv].code_90[lcv2]&0xff );
  3540. + }
  3541. +
  3542. +
  3543. + // polyphonic aftertouch
  3544. + MIDI_RawOutByte( 0xa0+lcv );
  3545. +
  3546. + for( int lcv2=0; lcv2<0x80; lcv2++ ) {
  3547. + if( midi_state[lcv].code_a0[lcv2] == 0xffff ) continue;
  3548. +
  3549. +
  3550. + //MIDI_RawOutByte( 0xa0+lcv );
  3551. + MIDI_RawOutByte( lcv2 );
  3552. + MIDI_RawOutByte( midi_state[lcv].code_a0[lcv2]&0xff );
  3553. + }
  3554. +
  3555. +
  3556. + // channel aftertouch
  3557. + if( midi_state[lcv].code_d0[0] != 0xffff ) {
  3558. + MIDI_RawOutByte( 0xd0+lcv );
  3559. + MIDI_RawOutByte( midi_state[lcv].code_d0[0]&0xff );
  3560. + }
  3561. + }
  3562. +
  3563. + midi_state[0].ignore = false;
  3564. +}
  3565. +
  3566. void MIDI_RawOutByte(Bit8u data) {
  3567. if (midi.sysex.start) {
  3568. Bit32u passed_ticks = GetTicks() - midi.sysex.start;
  3569. @@ -151,6 +589,9 @@
  3570. if (CaptureState & CAPTURE_MIDI) {
  3571. CAPTURE_AddMidi(false, midi.cmd_len, midi.cmd_buf);
  3572. }
  3573. +
  3574. + MIDI_State_SaveMessage();
  3575. +
  3576. midi.handler->PlayMsg(midi.cmd_buf);
  3577. midi.cmd_pos=1; //Use Running status
  3578. }
  3579. @@ -205,6 +646,12 @@
  3580. midi.available=true;
  3581. midi.handler=handler;
  3582. LOG_MSG("MIDI: Opened device:%s",handler->GetName());
  3583. +
  3584. + // force reset to prevent crashes (when not properly shutdown)
  3585. + // ex. Roland VSC = unexpected hard system crash
  3586. + midi_state[0].init = false;
  3587. + MIDI_State_LoadMessage();
  3588. +
  3589. return;
  3590. }
  3591. handler=handler->next;
  3592. @@ -212,6 +659,16 @@
  3593. /* This shouldn't be possible */
  3594. }
  3595. ~MIDI(){
  3596. +
  3597. + if( midi.status < 0xf0 ) {
  3598. + // throw invalid midi message - start new cmd
  3599. + MIDI_RawOutByte(0x80);
  3600. + }
  3601. + else if( midi.status == 0xf0 ) {
  3602. + // SysEx - throw invalid midi message
  3603. + MIDI_RawOutByte(0xf7);
  3604. + }
  3605. +
  3606. if(midi.available) midi.handler->Close();
  3607. midi.available = false;
  3608. midi.handler = 0;
  3609. @@ -227,3 +684,110 @@
  3610. test = new MIDI(sec);
  3611. sec->AddDestroyFunction(&MIDI_Destroy,true);
  3612. }
  3613. +
  3614. +//save state support
  3615. +namespace {
  3616. +class SerializeMidi : public SerializeGlobalPOD {
  3617. +public:
  3618. + SerializeMidi() : SerializeGlobalPOD("Midi")
  3619. + {}
  3620. +
  3621. +private:
  3622. + virtual void getBytes(std::ostream& stream)
  3623. + {
  3624. + if( !test ) return;
  3625. +
  3626. + //******************************************
  3627. + //******************************************
  3628. + //******************************************
  3629. +
  3630. + SerializeGlobalPOD::getBytes(stream);
  3631. +
  3632. +
  3633. + // - pure data
  3634. + WRITE_POD( &midi.status, midi.status );
  3635. + WRITE_POD( &midi.cmd_len, midi.cmd_len );
  3636. + WRITE_POD( &midi.cmd_pos, midi.cmd_pos );
  3637. + WRITE_POD( &midi.cmd_buf, midi.cmd_buf );
  3638. + WRITE_POD( &midi.rt_buf, midi.rt_buf );
  3639. + WRITE_POD( &midi.sysex, midi.sysex );
  3640. +
  3641. + //*******************************************
  3642. + //*******************************************
  3643. + //*******************************************
  3644. +
  3645. + // Supports MT-32 MUNT only!!
  3646. + if(0) {
  3647. + }
  3648. +
  3649. + // external MIDI
  3650. + else if( midi.available ) {
  3651. + const char pod_name[32] = "External";
  3652. +
  3653. +
  3654. + WRITE_POD( &pod_name, pod_name );
  3655. +
  3656. + //*******************************************
  3657. + //*******************************************
  3658. + //*******************************************
  3659. +
  3660. + // - pure data
  3661. + WRITE_POD( &midi_state, midi_state );
  3662. + }
  3663. + }
  3664. +
  3665. + virtual void setBytes(std::istream& stream)
  3666. + {
  3667. + if( !test ) return;
  3668. +
  3669. + //******************************************
  3670. + //******************************************
  3671. + //******************************************
  3672. +
  3673. + SerializeGlobalPOD::setBytes(stream);
  3674. +
  3675. +
  3676. + // - pure data
  3677. + READ_POD( &midi.status, midi.status );
  3678. + READ_POD( &midi.cmd_len, midi.cmd_len );
  3679. + READ_POD( &midi.cmd_pos, midi.cmd_pos );
  3680. + READ_POD( &midi.cmd_buf, midi.cmd_buf );
  3681. + READ_POD( &midi.rt_buf, midi.rt_buf );
  3682. + READ_POD( &midi.sysex, midi.sysex );
  3683. +
  3684. + //*******************************************
  3685. + //*******************************************
  3686. + //*******************************************
  3687. +
  3688. + // Supports MT-32 MUNT only!!
  3689. + if(0) {
  3690. + }
  3691. +
  3692. + // external MIDI
  3693. + else if( midi.available ) {
  3694. + char pod_name[32] = {0};
  3695. +
  3696. +
  3697. + // error checking
  3698. + READ_POD( &pod_name, pod_name );
  3699. + if( strcmp( pod_name, "External" ) ) {
  3700. + stream.clear( std::istream::failbit | std::istream::badbit );
  3701. + return;
  3702. + }
  3703. +
  3704. + //************************************************
  3705. + //************************************************
  3706. + //************************************************
  3707. +
  3708. + // - pure data
  3709. + READ_POD( &midi_state, midi_state );
  3710. +
  3711. + //************************************************
  3712. + //************************************************
  3713. + //************************************************
  3714. +
  3715. + MIDI_State_LoadMessage();
  3716. + }
  3717. + }
  3718. +} dummy;
  3719. +}
  3720. \ No newline at end of file
  3721. Index: src/gui/render.cpp
  3722. ===================================================================
  3723. --- src/gui/render.cpp (revision 4176)
  3724. +++ src/gui/render.cpp (working copy)
  3725. @@ -31,6 +31,8 @@
  3726. #include "hardware.h"
  3727. #include "support.h"
  3728.  
  3729. +#include "../save_state.h"
  3730. +
  3731. #include "render_scalers.h"
  3732.  
  3733. Render_t render;
  3734. @@ -631,3 +633,55 @@
  3735. GFX_SetTitle(-1,render.frameskip.max,false);
  3736. }
  3737.  
  3738. +//save state support
  3739. +namespace
  3740. +{
  3741. +class SerializeRender : public SerializeGlobalPOD
  3742. +{
  3743. +public:
  3744. + SerializeRender() : SerializeGlobalPOD("Render")
  3745. + {}
  3746. +
  3747. +private:
  3748. + virtual void getBytes(std::ostream& stream)
  3749. + {
  3750. + SerializeGlobalPOD::getBytes(stream);
  3751. +
  3752. +
  3753. + // - pure data
  3754. + WRITE_POD( &render.src, render.src );
  3755. +
  3756. + WRITE_POD( &render.pal, render.pal );
  3757. + WRITE_POD( &render.updating, render.updating );
  3758. + WRITE_POD( &render.active, render.active );
  3759. + WRITE_POD( &render.fullFrame, render.fullFrame );
  3760. + WRITE_POD( &render.frameskip, render.frameskip );
  3761. + }
  3762. +
  3763. + virtual void setBytes(std::istream& stream)
  3764. + {
  3765. + SerializeGlobalPOD::setBytes(stream);
  3766. +
  3767. +
  3768. + // - pure data
  3769. + READ_POD( &render.src, render.src );
  3770. +
  3771. + READ_POD( &render.pal, render.pal );
  3772. + READ_POD( &render.updating, render.updating );
  3773. + READ_POD( &render.active, render.active );
  3774. + READ_POD( &render.fullFrame, render.fullFrame );
  3775. + READ_POD( &render.frameskip, render.frameskip );
  3776. +
  3777. + //***************************************
  3778. + //***************************************
  3779. +
  3780. + // reset screen
  3781. + //memset( &render.frameskip, 0, sizeof(render.frameskip) );
  3782. +
  3783. + render.scale.clearCache = true;
  3784. + if( render.scale.outWrite ) { GFX_EndUpdate(NULL); }
  3785. +
  3786. + RENDER_SetSize( render.src.width, render.src.height, render.src.bpp, render.src.fps, render.src.ratio, render.src.dblw, render.src.dblh );
  3787. + }
  3788. +} dummy;
  3789. +}
  3790. \ No newline at end of file
  3791. Index: src/gui/sdlmain.cpp
  3792. ===================================================================
  3793. --- src/gui/sdlmain.cpp (revision 4176)
  3794. +++ src/gui/sdlmain.cpp (working copy)
  3795. @@ -50,6 +50,8 @@
  3796. #include "cross.h"
  3797. #include "control.h"
  3798.  
  3799. +#include "../save_state.h"
  3800. +
  3801. #define MAPPERFILE "mapper-" VERSION ".map"
  3802. //#define DISABLE_JOYSTICK
  3803.  
  3804. @@ -2193,3 +2195,29 @@
  3805. height = sdl.draw.height;
  3806. fullscreen = sdl.desktop.fullscreen;
  3807. }
  3808. +
  3809. +bool Get_Custom_SaveDir(std::string& savedir) {
  3810. + std::string custom_savedir;
  3811. + if (control->cmdline->FindString("-savedir",custom_savedir,false)) {
  3812. + savedir=custom_savedir;
  3813. + return true;
  3814. + } else {
  3815. + return false;
  3816. + }
  3817. +}
  3818. +
  3819. +// save state support
  3820. +void POD_Save_Sdlmain( std::ostream& stream )
  3821. +{
  3822. + // - pure data
  3823. + WRITE_POD( &sdl.mouse.autolock, sdl.mouse.autolock );
  3824. + WRITE_POD( &sdl.mouse.requestlock, sdl.mouse.requestlock );
  3825. +}
  3826. +
  3827. +
  3828. +void POD_Load_Sdlmain( std::istream& stream )
  3829. +{
  3830. + // - pure data
  3831. + READ_POD( &sdl.mouse.autolock, sdl.mouse.autolock );
  3832. + READ_POD( &sdl.mouse.requestlock, sdl.mouse.requestlock );
  3833. +}
  3834. \ No newline at end of file
  3835. Index: src/hardware/adlib.cpp
  3836. ===================================================================
  3837. --- src/hardware/adlib.cpp (revision 4176)
  3838. +++ src/hardware/adlib.cpp (working copy)
  3839. @@ -35,6 +35,8 @@
  3840. #define OPL2_INTERNAL_FREQ 3600000 // The OPL2 operates at 3.6MHz
  3841. #define OPL3_INTERNAL_FREQ 14400000 // The OPL3 operates at 14.4MHz
  3842.  
  3843. +#include "../save_state.h"
  3844. +
  3845. namespace OPL2 {
  3846. #include "opl.cpp"
  3847.  
  3848. @@ -58,6 +60,42 @@
  3849. virtual void Init( Bitu rate ) {
  3850. adlib_init(rate);
  3851. }
  3852. +
  3853. + virtual void SaveState( std::ostream& stream ) {
  3854. + const char pod_name[32] = "OPL2";
  3855. +
  3856. + if( stream.fail() ) return;
  3857. +
  3858. +
  3859. + WRITE_POD( &pod_name, pod_name );
  3860. +
  3861. + //************************************************
  3862. + //************************************************
  3863. + //************************************************
  3864. +
  3865. + adlib_savestate(stream);
  3866. + }
  3867. +
  3868. + virtual void LoadState( std::istream& stream ) {
  3869. + char pod_name[32] = {0};
  3870. +
  3871. + if( stream.fail() ) return;
  3872. +
  3873. +
  3874. + // error checking
  3875. + READ_POD( &pod_name, pod_name );
  3876. + if( strcmp( pod_name, "OPL2" ) ) {
  3877. + stream.clear( std::istream::failbit | std::istream::badbit );
  3878. + return;
  3879. + }
  3880. +
  3881. + //************************************************
  3882. + //************************************************
  3883. + //************************************************
  3884. +
  3885. + adlib_loadstate(stream);
  3886. + }
  3887. +
  3888. ~Handler() {
  3889. }
  3890. };
  3891. @@ -87,6 +125,42 @@
  3892. virtual void Init( Bitu rate ) {
  3893. adlib_init(rate);
  3894. }
  3895. +
  3896. + virtual void SaveState( std::ostream& stream ) {
  3897. + const char pod_name[32] = "OPL3";
  3898. +
  3899. + if( stream.fail() ) return;
  3900. +
  3901. +
  3902. + WRITE_POD( &pod_name, pod_name );
  3903. +
  3904. + //************************************************
  3905. + //************************************************
  3906. + //************************************************
  3907. +
  3908. + adlib_savestate(stream);
  3909. + }
  3910. +
  3911. + virtual void LoadState( std::istream& stream ) {
  3912. + char pod_name[32] = {0};
  3913. +
  3914. + if( stream.fail() ) return;
  3915. +
  3916. +
  3917. + // error checking
  3918. + READ_POD( &pod_name, pod_name );
  3919. + if( strcmp( pod_name, "OPL3" ) ) {
  3920. + stream.clear( std::istream::failbit | std::istream::badbit );
  3921. + return;
  3922. + }
  3923. +
  3924. + //************************************************
  3925. + //************************************************
  3926. + //************************************************
  3927. +
  3928. + adlib_loadstate(stream);
  3929. + }
  3930. +
  3931. ~Handler() {
  3932. }
  3933. };
  3934. @@ -116,6 +190,42 @@
  3935. virtual void Init(Bitu rate) {
  3936. chip = ym3812_init(0, OPL2_INTERNAL_FREQ, rate);
  3937. }
  3938. +
  3939. + virtual void SaveState( std::ostream& stream ) {
  3940. + const char pod_name[32] = "MAMEOPL2";
  3941. +
  3942. + if( stream.fail() ) return;
  3943. +
  3944. +
  3945. + WRITE_POD( &pod_name, pod_name );
  3946. +
  3947. + //************************************************
  3948. + //************************************************
  3949. + //************************************************
  3950. +
  3951. + FMOPL_SaveState(chip, stream);
  3952. + }
  3953. +
  3954. + virtual void LoadState( std::istream& stream ) {
  3955. + char pod_name[32] = {0};
  3956. +
  3957. + if( stream.fail() ) return;
  3958. +
  3959. +
  3960. + // error checking
  3961. + READ_POD( &pod_name, pod_name );
  3962. + if( strcmp( pod_name, "MAMEOPL2" ) ) {
  3963. + stream.clear( std::istream::failbit | std::istream::badbit );
  3964. + return;
  3965. + }
  3966. +
  3967. + //************************************************
  3968. + //************************************************
  3969. + //************************************************
  3970. +
  3971. + FMOPL_LoadState(chip, stream);
  3972. + }
  3973. +
  3974. ~Handler() {
  3975. ym3812_shutdown(chip);
  3976. }
  3977. @@ -157,6 +267,42 @@
  3978. virtual void Init(Bitu rate) {
  3979. chip = ymf262_init(0, OPL3_INTERNAL_FREQ, rate);
  3980. }
  3981. +
  3982. + virtual void SaveState( std::ostream& stream ) {
  3983. + const char pod_name[32] = "MAMEOPL3";
  3984. +
  3985. + if( stream.fail() ) return;
  3986. +
  3987. +
  3988. + WRITE_POD( &pod_name, pod_name );
  3989. +
  3990. + //************************************************
  3991. + //************************************************
  3992. + //************************************************
  3993. +
  3994. + YMF_SaveState(chip, stream);
  3995. + }
  3996. +
  3997. + virtual void LoadState( std::istream& stream ) {
  3998. + char pod_name[32] = {0};
  3999. +
  4000. + if( stream.fail() ) return;
  4001. +
  4002. +
  4003. + // error checking
  4004. + READ_POD( &pod_name, pod_name );
  4005. + if( strcmp( pod_name, "MAMEOPL3" ) ) {
  4006. + stream.clear( std::istream::failbit | std::istream::badbit );
  4007. + return;
  4008. + }
  4009. +
  4010. + //************************************************
  4011. + //************************************************
  4012. + //************************************************
  4013. +
  4014. + YMF_LoadState(chip, stream);
  4015. + }
  4016. +
  4017. ~Handler() {
  4018. ymf262_shutdown(chip);
  4019. }
  4020. @@ -866,3 +1012,79 @@
  4021. module = 0;
  4022.  
  4023. }
  4024. +
  4025. +// savestate support
  4026. +void Adlib::Module::SaveState( std::ostream& stream )
  4027. +{
  4028. + // - pure data
  4029. + WRITE_POD( &mode, mode );
  4030. + WRITE_POD( &reg, reg );
  4031. + WRITE_POD( &ctrl, ctrl );
  4032. + WRITE_POD( &oplmode, oplmode );
  4033. + WRITE_POD( &lastUsed, lastUsed );
  4034. +
  4035. + handler->SaveState(stream);
  4036. +
  4037. + WRITE_POD( &cache, cache );
  4038. + WRITE_POD( &chip, chip );
  4039. +}
  4040. +
  4041. +void Adlib::Module::LoadState( std::istream& stream )
  4042. +{
  4043. + // - pure data
  4044. + READ_POD( &mode, mode );
  4045. + READ_POD( &reg, reg );
  4046. + READ_POD( &ctrl, ctrl );
  4047. + READ_POD( &oplmode, oplmode );
  4048. + READ_POD( &lastUsed, lastUsed );
  4049. +
  4050. + handler->LoadState(stream);
  4051. +
  4052. + READ_POD( &cache, cache );
  4053. + READ_POD( &chip, chip );
  4054. +}
  4055. +
  4056. +
  4057. +void POD_Save_Adlib(std::ostream& stream)
  4058. +{
  4059. + const char pod_name[32] = "Adlib";
  4060. +
  4061. + if( stream.fail() ) return;
  4062. + if( !module ) return;
  4063. + if( !module->mixerChan ) return;
  4064. +
  4065. +
  4066. + WRITE_POD( &pod_name, pod_name );
  4067. +
  4068. + //************************************************
  4069. + //************************************************
  4070. + //************************************************
  4071. +
  4072. + module->SaveState(stream);
  4073. + module->mixerChan->SaveState(stream);
  4074. +}
  4075. +
  4076. +
  4077. +void POD_Load_Adlib(std::istream& stream)
  4078. +{
  4079. + char pod_name[32] = {0};
  4080. +
  4081. + if( stream.fail() ) return;
  4082. + if( !module ) return;
  4083. + if( !module->mixerChan ) return;
  4084. +
  4085. +
  4086. + // error checking
  4087. + READ_POD( &pod_name, pod_name );
  4088. + if( strcmp( pod_name, "Adlib" ) ) {
  4089. + stream.clear( std::istream::failbit | std::istream::badbit );
  4090. + return;
  4091. + }
  4092. +
  4093. + //************************************************
  4094. + //************************************************
  4095. + //************************************************
  4096. +
  4097. + module->LoadState(stream);
  4098. + module->mixerChan->LoadState(stream);
  4099. +}
  4100. \ No newline at end of file
  4101. Index: src/hardware/adlib.h
  4102. ===================================================================
  4103. --- src/hardware/adlib.h (revision 4176)
  4104. +++ src/hardware/adlib.h (working copy)
  4105. @@ -104,6 +104,10 @@
  4106. virtual void Generate( MixerChannel* chan, Bitu samples ) = 0;
  4107. //Initialize at a specific sample rate and mode
  4108. virtual void Init( Bitu rate ) = 0;
  4109. +
  4110. + virtual void SaveState( std::ostream& stream ) {}
  4111. + virtual void LoadState( std::istream& stream ) {}
  4112. +
  4113. virtual ~Handler() {
  4114. }
  4115. };
  4116. @@ -152,6 +156,10 @@
  4117. Bitu PortRead( Bitu port, Bitu iolen );
  4118. void Init( Mode m );
  4119.  
  4120. + // savestate support
  4121. + virtual void SaveState( std::ostream& stream );
  4122. + virtual void LoadState( std::istream& stream );
  4123. +
  4124. Module( Section* configuration);
  4125. ~Module();
  4126. };
  4127. Index: src/hardware/cmos.cpp
  4128. ===================================================================
  4129. --- src/hardware/cmos.cpp (revision 4176)
  4130. +++ src/hardware/cmos.cpp (working copy)
  4131. @@ -29,6 +29,8 @@
  4132. #include "setup.h"
  4133. #include "cross.h" //fmod on certain platforms
  4134.  
  4135. +#include "../save_state.h"
  4136. +
  4137. static struct {
  4138. Bit8u regs[0x40];
  4139. bool nmi;
  4140. @@ -328,3 +330,28 @@
  4141. test = new CMOS(sec);
  4142. sec->AddDestroyFunction(&CMOS_Destroy,true);
  4143. }
  4144. +
  4145. +// save state support
  4146. +void *cmos_timerevent_PIC_Event = (void*)cmos_timerevent;
  4147. +
  4148. +namespace
  4149. +{
  4150. +class SerializeCmos : public SerializeGlobalPOD
  4151. +{
  4152. +public:
  4153. + SerializeCmos() : SerializeGlobalPOD("CMOS")
  4154. + {
  4155. + registerPOD(cmos.regs);
  4156. + registerPOD(cmos.nmi);
  4157. + registerPOD(cmos.reg);
  4158. + registerPOD(cmos.timer.enabled);
  4159. + registerPOD(cmos.timer.div);
  4160. + registerPOD(cmos.timer.delay);
  4161. + registerPOD(cmos.timer.acknowledged);
  4162. + registerPOD(cmos.last.timer);
  4163. + registerPOD(cmos.last.ended);
  4164. + registerPOD(cmos.last.alarm);
  4165. + registerPOD(cmos.update_ended);
  4166. + }
  4167. +} dummy;
  4168. +}
  4169. \ No newline at end of file
  4170. Index: src/hardware/dbopl.cpp
  4171. ===================================================================
  4172. --- src/hardware/dbopl.cpp (revision 4176)
  4173. +++ src/hardware/dbopl.cpp (working copy)
  4174. @@ -40,7 +40,9 @@
  4175. #include "dosbox.h"
  4176. #include "dbopl.h"
  4177.  
  4178. +#include "../save_state.h"
  4179.  
  4180. +
  4181. #ifndef PI
  4182. #define PI 3.14159265358979323846
  4183. #endif
  4184. @@ -1517,5 +1519,156 @@
  4185. chip.Setup( rate );
  4186. }
  4187.  
  4188. +// save state support
  4189. +void Handler::SaveState( std::ostream& stream )
  4190. +{
  4191. + const char pod_name[32] = "DBOPL";
  4192.  
  4193. + if( stream.fail() ) return;
  4194. +
  4195. +
  4196. + WRITE_POD( &pod_name, pod_name );
  4197. +
  4198. + //************************************************
  4199. + //************************************************
  4200. + //************************************************
  4201. +
  4202. + Bit8u volhandler_idx[18][2];
  4203. + Bit32u wavebase_idx[18][2];
  4204. + Bit8u synthhandler_idx[18];
  4205. +
  4206. +
  4207. + for( int lcv1=0; lcv1<18; lcv1++ ) {
  4208. + for( int lcv2=0; lcv2<2; lcv2++ ) {
  4209. + volhandler_idx[lcv1][lcv2] = 0xff;
  4210. +
  4211. + for( int lcv3=0; lcv3<5; lcv3++ ) {
  4212. + if( chip.chan[lcv1].op[lcv2].volHandler == VolumeHandlerTable[lcv3] ) {
  4213. + volhandler_idx[lcv1][lcv2] = lcv3;
  4214. + break;
  4215. + }
  4216. + }
  4217. +
  4218. + wavebase_idx[lcv1][lcv2] = (Bitu) chip.chan[lcv1].op[lcv2].waveBase - (Bitu) &WaveTable;
  4219. + }
  4220. +
  4221. +
  4222. + synthhandler_idx[lcv1] = 0xff;
  4223. + if(0) {}
  4224. + else if( chip.chan[lcv1].synthHandler == &Channel::BlockTemplate< sm3FMFM > ) synthhandler_idx[lcv1] = 0x00;
  4225. + else if( chip.chan[lcv1].synthHandler == &Channel::BlockTemplate< sm3AMFM > ) synthhandler_idx[lcv1] = 0x01;
  4226. + else if( chip.chan[lcv1].synthHandler == &Channel::BlockTemplate< sm3FMAM > ) synthhandler_idx[lcv1] = 0x02;
  4227. + else if( chip.chan[lcv1].synthHandler == &Channel::BlockTemplate< sm3AMAM > ) synthhandler_idx[lcv1] = 0x03;
  4228. + else if( chip.chan[lcv1].synthHandler == &Channel::BlockTemplate< sm3AM > ) synthhandler_idx[lcv1] = 0x04;
  4229. + else if( chip.chan[lcv1].synthHandler == &Channel::BlockTemplate< sm3FM > ) synthhandler_idx[lcv1] = 0x05;
  4230. + else if( chip.chan[lcv1].synthHandler == &Channel::BlockTemplate< sm2AM > ) synthhandler_idx[lcv1] = 0x06;
  4231. + else if( chip.chan[lcv1].synthHandler == &Channel::BlockTemplate< sm2FM > ) synthhandler_idx[lcv1] = 0x07;
  4232. + else if( chip.chan[lcv1].synthHandler == &Channel::BlockTemplate< sm3Percussion > ) synthhandler_idx[lcv1] = 0x08;
  4233. + else if( chip.chan[lcv1].synthHandler == &Channel::BlockTemplate< sm2Percussion > ) synthhandler_idx[lcv1] = 0x09;
  4234. + }
  4235. +
  4236. + //***************************************************
  4237. + //***************************************************
  4238. + //***************************************************
  4239. +
  4240. + // dbopl.cpp
  4241. +
  4242. + // - pure data
  4243. + WRITE_POD( &WaveTable, WaveTable );
  4244. + WRITE_POD( &doneTables, doneTables );
  4245. +
  4246. + //***************************************************
  4247. + //***************************************************
  4248. + //***************************************************
  4249. +
  4250. + // dbopl.h
  4251. +
  4252. + // - near-pure data
  4253. + WRITE_POD( &chip, chip );
  4254. +
  4255. +
  4256. +
  4257. +
  4258. + // - reloc ptr (!!!)
  4259. + WRITE_POD( &volhandler_idx, volhandler_idx );
  4260. + WRITE_POD( &wavebase_idx, wavebase_idx );
  4261. + WRITE_POD( &synthhandler_idx, synthhandler_idx );
  4262. +}
  4263. +
  4264. +void Handler::LoadState( std::istream& stream )
  4265. +{
  4266. + char pod_name[32] = {0};
  4267. +
  4268. + if( stream.fail() ) return;
  4269. +
  4270. +
  4271. + // error checking
  4272. + READ_POD( &pod_name, pod_name );
  4273. + if( strcmp( pod_name, "DBOPL" ) ) {
  4274. + stream.clear( std::istream::failbit | std::istream::badbit );
  4275. + return;
  4276. + }
  4277. +
  4278. + //************************************************
  4279. + //************************************************
  4280. + //************************************************
  4281. +
  4282. + Bit8u volhandler_idx[18][2];
  4283. + Bit32u wavebase_idx[18][2];
  4284. + Bit8u synthhandler_idx[18];
  4285. +
  4286. + //***************************************************
  4287. + //***************************************************
  4288. + //***************************************************
  4289. +
  4290. + // dbopl.cpp
  4291. +
  4292. + // - pure data
  4293. + READ_POD( &WaveTable, WaveTable );
  4294. + READ_POD( &doneTables, doneTables );
  4295. +
  4296. + //***************************************************
  4297. + //***************************************************
  4298. + //***************************************************
  4299. +
  4300. + // dbopl.h
  4301. +
  4302. + // - near-pure data
  4303. + READ_POD( &chip, chip );
  4304. +
  4305. +
  4306. +
  4307. +
  4308. + // - reloc ptr (!!!)
  4309. + READ_POD( &volhandler_idx, volhandler_idx );
  4310. + READ_POD( &wavebase_idx, wavebase_idx );
  4311. + READ_POD( &synthhandler_idx, synthhandler_idx );
  4312. +
  4313. + //***************************************************
  4314. + //***************************************************
  4315. + //***************************************************
  4316. +
  4317. + for( int lcv1=0; lcv1<18; lcv1++ ) {
  4318. + for( int lcv2=0; lcv2<2; lcv2++ ) {
  4319. + chip.chan[lcv1].op[lcv2].volHandler = VolumeHandlerTable[ volhandler_idx[lcv1][lcv2] ];
  4320. +
  4321. + chip.chan[lcv1].op[lcv2].waveBase = (Bit16s *) ((Bitu) wavebase_idx[lcv1][lcv2] + (Bitu) &WaveTable);
  4322. + }
  4323. +
  4324. +
  4325. + switch( synthhandler_idx[lcv1] ) {
  4326. + case 0x00: chip.chan[lcv1].synthHandler = &Channel::BlockTemplate< sm3FMFM >; break;
  4327. + case 0x01: chip.chan[lcv1].synthHandler = &Channel::BlockTemplate< sm3AMFM >; break;
  4328. + case 0x02: chip.chan[lcv1].synthHandler = &Channel::BlockTemplate< sm3FMAM >; break;
  4329. + case 0x03: chip.chan[lcv1].synthHandler = &Channel::BlockTemplate< sm3AMAM >; break;
  4330. + case 0x04: chip.chan[lcv1].synthHandler = &Channel::BlockTemplate< sm3AM >; break;
  4331. + case 0x05: chip.chan[lcv1].synthHandler = &Channel::BlockTemplate< sm3FM >; break;
  4332. + case 0x06: chip.chan[lcv1].synthHandler = &Channel::BlockTemplate< sm2AM >; break;
  4333. + case 0x07: chip.chan[lcv1].synthHandler = &Channel::BlockTemplate< sm2FM >; break;
  4334. + case 0x08: chip.chan[lcv1].synthHandler = &Channel::BlockTemplate< sm3Percussion >; break;
  4335. + case 0x09: chip.chan[lcv1].synthHandler = &Channel::BlockTemplate< sm2Percussion >; break;
  4336. + }
  4337. + }
  4338. +}
  4339. +
  4340. }; //Namespace DBOPL
  4341. Index: src/hardware/dbopl.h
  4342. ===================================================================
  4343. --- src/hardware/dbopl.h (revision 4176)
  4344. +++ src/hardware/dbopl.h (working copy)
  4345. @@ -253,6 +253,10 @@
  4346. virtual void WriteReg( Bit32u addr, Bit8u val );
  4347. virtual void Generate( MixerChannel* chan, Bitu samples );
  4348. virtual void Init( Bitu rate );
  4349. +
  4350. + virtual void SaveState( std::ostream& stream );
  4351. + virtual void LoadState( std::istream& stream );
  4352. +
  4353. };
  4354.  
  4355.  
  4356. Index: src/hardware/disney.cpp
  4357. ===================================================================
  4358. --- src/hardware/disney.cpp (revision 4176)
  4359. +++ src/hardware/disney.cpp (working copy)
  4360. @@ -24,6 +24,8 @@
  4361. #include "pic.h"
  4362. #include "setup.h"
  4363.  
  4364. +#include "../save_state.h"
  4365. +
  4366. #define DISNEY_BASE 0x0378
  4367.  
  4368. #define DISNEY_SIZE 128
  4369. @@ -397,3 +399,111 @@
  4370. test = new DISNEY(sec);
  4371. sec->AddDestroyFunction(&DISNEY_ShutDown,true);
  4372. }
  4373. +
  4374. +// save state support
  4375. +void *DISNEY_disable_PIC_Event = (void*)DISNEY_disable;
  4376. +
  4377. +
  4378. +void POD_Save_Disney( std::ostream& stream )
  4379. +{
  4380. + const char pod_name[32] = "Disney";
  4381. +
  4382. + if( stream.fail() ) return;
  4383. + if( !test ) return;
  4384. + if( !disney.chan ) return;
  4385. +
  4386. +
  4387. + WRITE_POD( &pod_name, pod_name );
  4388. +
  4389. + //************************************************
  4390. + //************************************************
  4391. + //************************************************
  4392. +
  4393. + Bit8u dac_leader_idx;
  4394. +
  4395. +
  4396. + dac_leader_idx = 0xff;
  4397. + for( int lcv=0; lcv<2; lcv++ ) {
  4398. + if( disney.leader == &disney.da[lcv] ) { dac_leader_idx = lcv; break; }
  4399. + }
  4400. +
  4401. + // *******************************************
  4402. + // *******************************************
  4403. + // *******************************************
  4404. +
  4405. + // - near-pure struct data
  4406. + WRITE_POD( &disney, disney );
  4407. +
  4408. +
  4409. +
  4410. +
  4411. + // - reloc ptr
  4412. + WRITE_POD( &dac_leader_idx, dac_leader_idx );
  4413. +
  4414. + //*******************************************
  4415. + //*******************************************
  4416. + //*******************************************
  4417. +
  4418. + disney.chan->SaveState(stream);
  4419. +}
  4420. +
  4421. +
  4422. +void POD_Load_Disney( std::istream& stream )
  4423. +{
  4424. + char pod_name[32] = {0};
  4425. +
  4426. + if( stream.fail() ) return;
  4427. + if( !test ) return;
  4428. + if( !disney.chan ) return;
  4429. +
  4430. +
  4431. + // error checking
  4432. + READ_POD( &pod_name, pod_name );
  4433. + if( strcmp( pod_name, "Disney" ) ) {
  4434. + stream.clear( std::istream::failbit | std::istream::badbit );
  4435. + return;
  4436. + }
  4437. +
  4438. + //************************************************
  4439. + //************************************************
  4440. + //************************************************
  4441. +
  4442. + Bit8u dac_leader_idx;
  4443. + MixerObject *mo_old;
  4444. + MixerChannel *chan_old;
  4445. +
  4446. +
  4447. + // save old ptrs
  4448. + mo_old = disney.mo;
  4449. + chan_old = disney.chan;
  4450. +
  4451. + //*******************************************
  4452. + //*******************************************
  4453. + //*******************************************
  4454. +
  4455. + // - near-pure struct data
  4456. + READ_POD( &disney, disney );
  4457. +
  4458. +
  4459. +
  4460. + // - reloc ptr
  4461. + READ_POD( &dac_leader_idx, dac_leader_idx );
  4462. +
  4463. + //*******************************************
  4464. + //*******************************************
  4465. + //*******************************************
  4466. +
  4467. + disney.leader = NULL;
  4468. + if( dac_leader_idx != 0xff ) disney.leader = &disney.da[dac_leader_idx];
  4469. +
  4470. + //*******************************************
  4471. + //*******************************************
  4472. + //*******************************************
  4473. +
  4474. + // restore old ptrs
  4475. + disney.mo = mo_old;
  4476. + disney.chan = chan_old;
  4477. +
  4478. +
  4479. + disney.chan->LoadState(stream);
  4480. +}
  4481. \ No newline at end of file
  4482. Index: src/hardware/dma.cpp
  4483. ===================================================================
  4484. --- src/hardware/dma.cpp (revision 4176)
  4485. +++ src/hardware/dma.cpp (working copy)
  4486. @@ -26,6 +26,8 @@
  4487. #include "paging.h"
  4488. #include "setup.h"
  4489.  
  4490. +#include "../save_state.h"
  4491. +
  4492. DmaController *DmaControllers[2];
  4493.  
  4494. #define EMM_PAGEFRAME4K ((0xE000*16)/4096)
  4495. @@ -408,3 +410,195 @@
  4496. ems_board_mapping[i]=i;
  4497. }
  4498. }
  4499. +
  4500. +//save state support
  4501. +extern void *GUS_DMA_Callback_Func;
  4502. +extern void *SB_DSP_DMA_CallBack_Func;
  4503. +extern void *SB_DSP_ADC_CallBack_Func;
  4504. +extern void *SB_DSP_E2_DMA_CallBack_Func;
  4505. +extern void *TandyDAC_DMA_CallBack_Func;
  4506. +
  4507. +
  4508. +const void *dma_state_callback_table[] = {
  4509. + NULL,
  4510. + GUS_DMA_Callback_Func,
  4511. + SB_DSP_DMA_CallBack_Func,
  4512. + SB_DSP_ADC_CallBack_Func,
  4513. + SB_DSP_E2_DMA_CallBack_Func,
  4514. + TandyDAC_DMA_CallBack_Func
  4515. +};
  4516. +
  4517. +
  4518. +Bit8u POD_State_Find_DMA_Callback( Bitu addr )
  4519. +{
  4520. + Bit8u size;
  4521. +
  4522. + size = sizeof(dma_state_callback_table) / sizeof(void *);
  4523. + for( int lcv=0; lcv<size; lcv++ ) {
  4524. + if( (Bitu) dma_state_callback_table[lcv] == addr ) return lcv;
  4525. + }
  4526. +
  4527. +
  4528. + // ERROR! Set debug breakpoint
  4529. + return 0xff;
  4530. +}
  4531. +
  4532. +
  4533. +Bitu POD_State_Index_DMA_Callback( Bit8u index )
  4534. +{
  4535. + return (Bitu) dma_state_callback_table[index];
  4536. +}
  4537. +
  4538. +
  4539. +void DmaChannel::SaveState( std::ostream& stream )
  4540. +{
  4541. + Bit8u dma_callback;
  4542. +
  4543. +
  4544. + dma_callback = POD_State_Find_DMA_Callback( (Bitu) (callback) );
  4545. +
  4546. + //******************************************
  4547. + //******************************************
  4548. + //******************************************
  4549. +
  4550. + // - pure data
  4551. + WRITE_POD( &pagebase, pagebase );
  4552. + WRITE_POD( &baseaddr, baseaddr );
  4553. + WRITE_POD( &curraddr, curraddr );
  4554. + WRITE_POD( &basecnt, basecnt );
  4555. + WRITE_POD( &currcnt, currcnt );
  4556. + WRITE_POD( &channum, channum );
  4557. + WRITE_POD( &pagenum, pagenum );
  4558. + WRITE_POD( &DMA16, DMA16 );
  4559. + WRITE_POD( &increment, increment );
  4560. + WRITE_POD( &autoinit, autoinit );
  4561. + WRITE_POD( &trantype, trantype );
  4562. + WRITE_POD( &masked, masked );
  4563. + WRITE_POD( &tcount, tcount );
  4564. + WRITE_POD( &request, request );
  4565. +
  4566. + //******************************************
  4567. + //******************************************
  4568. + //******************************************
  4569. +
  4570. + // - reloc ptr (!!!)
  4571. + WRITE_POD( &dma_callback, dma_callback );
  4572. +}
  4573. +
  4574. +
  4575. +void DmaChannel::LoadState( std::istream& stream )
  4576. +{
  4577. + Bit8u dma_callback;
  4578. +
  4579. +
  4580. + dma_callback = POD_State_Find_DMA_Callback( (Bitu) (callback) );
  4581. +
  4582. + //******************************************
  4583. + //******************************************
  4584. + //******************************************
  4585. +
  4586. + // - pure data
  4587. + READ_POD( &pagebase, pagebase );
  4588. + READ_POD( &baseaddr, baseaddr );
  4589. + READ_POD( &curraddr, curraddr );
  4590. + READ_POD( &basecnt, basecnt );
  4591. + READ_POD( &currcnt, currcnt );
  4592. + READ_POD( &channum, channum );
  4593. + READ_POD( &pagenum, pagenum );
  4594. + READ_POD( &DMA16, DMA16 );
  4595. + READ_POD( &increment, increment );
  4596. + READ_POD( &autoinit, autoinit );
  4597. + READ_POD( &trantype, trantype );
  4598. + READ_POD( &masked, masked );
  4599. + READ_POD( &tcount, tcount );
  4600. + READ_POD( &request, request );
  4601. +
  4602. + //********************************
  4603. + //********************************
  4604. + //********************************
  4605. +
  4606. + // - reloc func ptr
  4607. + READ_POD( &dma_callback, dma_callback );
  4608. +
  4609. +
  4610. + callback = (DMA_CallBack) POD_State_Index_DMA_Callback( dma_callback );
  4611. +}
  4612. +
  4613. +
  4614. +void DmaController::SaveState( std::ostream& stream )
  4615. +{
  4616. + // - pure data
  4617. + WRITE_POD( &ctrlnum, ctrlnum );
  4618. + WRITE_POD( &flipflop, flipflop );
  4619. +
  4620. + for( int lcv=0; lcv<4; lcv++ ) {
  4621. + DmaChannels[lcv]->SaveState(stream);
  4622. + }
  4623. +}
  4624. +
  4625. +
  4626. +void DmaController::LoadState( std::istream& stream )
  4627. +{
  4628. + // - pure data
  4629. + READ_POD( &ctrlnum, ctrlnum );
  4630. + READ_POD( &flipflop, flipflop );
  4631. +
  4632. + for( int lcv=0; lcv<4; lcv++ ) {
  4633. + DmaChannels[lcv]->LoadState(stream);
  4634. + }
  4635. +}
  4636. +
  4637. +
  4638. +namespace
  4639. +{
  4640. + class SerializeDMA : public SerializeGlobalPOD
  4641. + {
  4642. + public:
  4643. + SerializeDMA() : SerializeGlobalPOD("DMA")
  4644. + {}
  4645. +
  4646. + private:
  4647. + virtual void getBytes(std::ostream& stream)
  4648. + {
  4649. + SerializeGlobalPOD::getBytes(stream);
  4650. +
  4651. +
  4652. + // - pure data
  4653. + WRITE_POD( &dma_wrapping, dma_wrapping );
  4654. +
  4655. +
  4656. + for( int lcv=0; lcv<2; lcv++ ) {
  4657. + // cga, tandy, pcjr = no 2nd controller
  4658. + if( !DmaControllers[lcv] ) continue;
  4659. +
  4660. + DmaControllers[lcv]->SaveState(stream);
  4661. + }
  4662. +
  4663. +
  4664. + // - pure data
  4665. + WRITE_POD( &ems_board_mapping, ems_board_mapping );
  4666. + }
  4667. +
  4668. + virtual void setBytes(std::istream& stream)
  4669. + {
  4670. + SerializeGlobalPOD::setBytes(stream);
  4671. +
  4672. +
  4673. + // - pure data
  4674. + READ_POD( &dma_wrapping, dma_wrapping );
  4675. +
  4676. +
  4677. + for( int lcv=0; lcv<2; lcv++ ) {
  4678. + // cga, tandy, pcjr = no 2nd controller
  4679. + if( !DmaControllers[lcv] ) continue;
  4680. +
  4681. + DmaControllers[lcv]->LoadState(stream);
  4682. + }
  4683. +
  4684. +
  4685. + // - pure data
  4686. + READ_POD( &ems_board_mapping, ems_board_mapping );
  4687. + }
  4688. + } dummy;
  4689. +}
  4690. +
  4691. Index: src/hardware/gameblaster.cpp
  4692. ===================================================================
  4693. --- src/hardware/gameblaster.cpp (revision 4176)
  4694. +++ src/hardware/gameblaster.cpp (working copy)
  4695. @@ -30,6 +30,7 @@
  4696. #include "mame/emu.h"
  4697. #include "mame/saa1099.h"
  4698.  
  4699. +#include "../save_state.h"
  4700. #define MASTER_CLOCK 7159090
  4701.  
  4702. //My mixer channel
  4703. @@ -171,3 +172,71 @@
  4704. void CMS_ShutDown(Section* sec) {
  4705. delete test;
  4706. }
  4707. +
  4708. +// save state support
  4709. +void POD_Save_Gameblaster( std::ostream& stream )
  4710. +{
  4711. + const char pod_name[32] = "CMS";
  4712. +
  4713. + if( stream.fail() ) return;
  4714. + if( !test ) return;
  4715. + if( !cms_chan ) return;
  4716. +
  4717. + WRITE_POD( &pod_name, pod_name );
  4718. +
  4719. + //*******************************************
  4720. + //*******************************************
  4721. + //*******************************************
  4722. +
  4723. + // - pure data
  4724. + WRITE_POD( &lastWriteTicks, lastWriteTicks );
  4725. + WRITE_POD( &cmsBase, cmsBase );
  4726. + WRITE_POD( &cms_detect_register, cms_detect_register );
  4727. +
  4728. + //************************************************
  4729. + //************************************************
  4730. + //************************************************
  4731. +
  4732. + for (int i=0; i<2; i++) {
  4733. + device[i]->SaveState(stream);
  4734. + }
  4735. +
  4736. + cms_chan->SaveState(stream);
  4737. +}
  4738. +
  4739. +
  4740. +void POD_Load_Gameblaster( std::istream& stream )
  4741. +{
  4742. + char pod_name[32] = {0};
  4743. +
  4744. + if( stream.fail() ) return;
  4745. + if( !test ) return;
  4746. + if( !cms_chan ) return;
  4747. +
  4748. +
  4749. + // error checking
  4750. + READ_POD( &pod_name, pod_name );
  4751. + if( strcmp( pod_name, "CMS" ) ) {
  4752. + stream.clear( std::istream::failbit | std::istream::badbit );
  4753. + return;
  4754. + }
  4755. +
  4756. + //*******************************************
  4757. + //*******************************************
  4758. + //*******************************************
  4759. +
  4760. + // - pure data
  4761. + READ_POD( &lastWriteTicks, lastWriteTicks );
  4762. + READ_POD( &cmsBase, cmsBase );
  4763. + READ_POD( &cms_detect_register, cms_detect_register );
  4764. +
  4765. + //************************************************
  4766. + //************************************************
  4767. + //************************************************
  4768. +
  4769. + for (int i=0; i<2; i++) {
  4770. + device[i]->LoadState(stream);
  4771. + }
  4772. +
  4773. + cms_chan->LoadState(stream);
  4774. +}
  4775. \ No newline at end of file
  4776. Index: src/hardware/gus.cpp
  4777. ===================================================================
  4778. --- src/hardware/gus.cpp (revision 4176)
  4779. +++ src/hardware/gus.cpp (working copy)
  4780. @@ -29,6 +29,9 @@
  4781. #include "shell.h"
  4782. #include "math.h"
  4783. #include "regs.h"
  4784. +
  4785. +#include "../save_state.h"
  4786. +
  4787. using namespace std;
  4788.  
  4789. //Extra bits of precision over normal gus
  4790. @@ -921,3 +924,124 @@
  4791. test = new GUS(sec);
  4792. sec->AddDestroyFunction(&GUS_ShutDown,true);
  4793. }
  4794. +
  4795. +// save state support
  4796. +void *GUS_TimerEvent_PIC_Event = (void*)GUS_TimerEvent;
  4797. +void *GUS_DMA_Callback_Func = (void*)GUS_DMA_Callback;
  4798. +
  4799. +
  4800. +void POD_Save_GUS( std::ostream& stream )
  4801. +{
  4802. + const char pod_name[32] = "GUS";
  4803. +
  4804. + if( stream.fail() ) return;
  4805. + if( !test ) return;
  4806. + if( !gus_chan ) return;
  4807. +
  4808. +
  4809. + WRITE_POD( &pod_name, pod_name );
  4810. +
  4811. + //*******************************************
  4812. + //*******************************************
  4813. + //*******************************************
  4814. +
  4815. + Bit8u curchan_idx;
  4816. +
  4817. +
  4818. + curchan_idx = 0xff;
  4819. + for( int lcv=0; lcv<32; lcv++ ) {
  4820. + if( curchan == guschan[lcv] ) { curchan_idx = lcv; break; }
  4821. + }
  4822. +
  4823. + // *******************************************
  4824. + // *******************************************
  4825. + // *******************************************
  4826. +
  4827. + // - pure data
  4828. + WRITE_POD( &adlib_commandreg, adlib_commandreg );
  4829. + WRITE_POD( &GUSRam, GUSRam );
  4830. + WRITE_POD( &vol16bit, vol16bit );
  4831. + WRITE_POD( &pantable, pantable );
  4832. +
  4833. + // - pure struct data
  4834. + WRITE_POD( &myGUS, myGUS );
  4835. +
  4836. +
  4837. + // - pure data
  4838. + for( int lcv=0; lcv<32; lcv++ ) {
  4839. + WRITE_POD( guschan[lcv], *guschan[lcv] );
  4840. + }
  4841. +
  4842. + // *******************************************
  4843. + // *******************************************
  4844. + // *******************************************
  4845. +
  4846. + // - reloc ptr
  4847. + WRITE_POD( &curchan_idx, curchan_idx );
  4848. +
  4849. + // *******************************************
  4850. + // *******************************************
  4851. + // *******************************************
  4852. +
  4853. + gus_chan->SaveState(stream);
  4854. +}
  4855. +
  4856. +
  4857. +void POD_Load_GUS( std::istream& stream )
  4858. +{
  4859. + char pod_name[32] = {0};
  4860. +
  4861. + if( stream.fail() ) return;
  4862. + if( !test ) return;
  4863. + if( !gus_chan ) return;
  4864. +
  4865. +
  4866. + // error checking
  4867. + READ_POD( &pod_name, pod_name );
  4868. + if( strcmp( pod_name, "GUS" ) ) {
  4869. + stream.clear( std::istream::failbit | std::istream::badbit );
  4870. + return;
  4871. + }
  4872. +
  4873. + //************************************************
  4874. + //************************************************
  4875. + //************************************************
  4876. +
  4877. + Bit8u curchan_idx;
  4878. +
  4879. + //*******************************************
  4880. + //*******************************************
  4881. + //*******************************************
  4882. +
  4883. + // - pure data
  4884. + READ_POD( &adlib_commandreg, adlib_commandreg );
  4885. + READ_POD( &GUSRam, GUSRam );
  4886. + READ_POD( &vol16bit, vol16bit );
  4887. + READ_POD( &pantable, pantable );
  4888. +
  4889. + READ_POD( &myGUS, myGUS );
  4890. +
  4891. + for( int lcv=0; lcv<32; lcv++ ) {
  4892. + if( !guschan[lcv] ) continue;
  4893. +
  4894. + READ_POD( guschan[lcv], *guschan[lcv] );
  4895. + }
  4896. +
  4897. +
  4898. +
  4899. + // - reloc ptr
  4900. + READ_POD( &curchan_idx, curchan_idx );
  4901. +
  4902. + //*******************************************
  4903. + //*******************************************
  4904. + //*******************************************
  4905. +
  4906. + curchan = NULL;
  4907. + if( curchan_idx != 0xff ) curchan = guschan[curchan_idx];
  4908. +
  4909. + //*******************************************
  4910. + //*******************************************
  4911. + //*******************************************
  4912. +
  4913. + gus_chan->LoadState(stream);
  4914. +}
  4915. \ No newline at end of file
  4916. Index: src/hardware/hardware.cpp
  4917. ===================================================================
  4918. --- src/hardware/hardware.cpp (revision 4176)
  4919. +++ src/hardware/hardware.cpp (working copy)
  4920. @@ -35,7 +35,7 @@
  4921. #include "../libs/zmbv/zmbv.cpp"
  4922. #endif
  4923.  
  4924. -static std::string capturedir;
  4925. +std::string capturedir;
  4926. extern const char* RunningProgram;
  4927. Bitu CaptureState;
  4928.  
  4929. Index: src/hardware/iohandler.cpp
  4930. ===================================================================
  4931. --- src/hardware/iohandler.cpp (revision 4176)
  4932. +++ src/hardware/iohandler.cpp (working copy)
  4933. @@ -25,6 +25,8 @@
  4934. #include "../src/cpu/lazyflags.h"
  4935. #include "callback.h"
  4936.  
  4937. +#include "../save_state.h"
  4938. +
  4939. //#define ENABLE_PORTLOG
  4940.  
  4941. IO_WriteHandler * io_writehandlers[3][IO_MAX];
  4942. @@ -527,3 +529,19 @@
  4943. test = new IO(sect);
  4944. sect->AddDestroyFunction(&IO_Destroy);
  4945. }
  4946. +
  4947. +//save state support
  4948. +namespace
  4949. +{
  4950. +class SerializeIO : public SerializeGlobalPOD
  4951. +{
  4952. +public:
  4953. + SerializeIO() : SerializeGlobalPOD("IO handler")
  4954. + {
  4955. + //io_writehandlers -> quasi constant
  4956. + //io_readhandlers -> quasi constant
  4957. +
  4958. + registerPOD(iof_queue.used); registerPOD(iof_queue.entries);
  4959. + }
  4960. +} dummy;
  4961. +}
  4962. \ No newline at end of file
  4963. Index: src/hardware/ipx.cpp
  4964. ===================================================================
  4965. --- src/hardware/ipx.cpp (revision 4176)
  4966. +++ src/hardware/ipx.cpp (working copy)
  4967. @@ -1197,4 +1197,10 @@
  4968. //Initialize static members;
  4969. Bit16u IPX::dospage = 0;
  4970.  
  4971. +// save state support
  4972. +#if C_IPX
  4973. +void *IPX_AES_EventHandler_PIC_Event = (void*)IPX_AES_EventHandler;
  4974. +void *IPX_ClientLoop_PIC_Timer = (void*)IPX_ClientLoop;
  4975. #endif
  4976. +
  4977. +#endif
  4978. Index: src/hardware/ipxserver.cpp
  4979. ===================================================================
  4980. --- src/hardware/ipxserver.cpp (revision 4176)
  4981. +++ src/hardware/ipxserver.cpp (working copy)
  4982. @@ -228,5 +228,7 @@
  4983. return false;
  4984. }
  4985.  
  4986. +// save state support
  4987. +void *IPX_ServerLoop_PIC_Timer = (void*)IPX_ServerLoop;
  4988.  
  4989. #endif
  4990. Index: src/hardware/joystick.cpp
  4991. ===================================================================
  4992. --- src/hardware/joystick.cpp (revision 4176)
  4993. +++ src/hardware/joystick.cpp (working copy)
  4994. @@ -26,6 +26,7 @@
  4995. #include "pic.h"
  4996. #include "support.h"
  4997.  
  4998. +#include "../save_state.h"
  4999.  
  5000. //TODO: higher axis can't be mapped. Find out why again
  5001.  
  5002. @@ -335,3 +336,22 @@
  5003. test = new JOYSTICK(sec);
  5004. sec->AddDestroyFunction(&JOYSTICK_Destroy,true);
  5005. }
  5006. +
  5007. +//save state support
  5008. +namespace
  5009. +{
  5010. +class SerializeStick : public SerializeGlobalPOD
  5011. +{
  5012. +public:
  5013. + SerializeStick() : SerializeGlobalPOD("Joystick")
  5014. + {
  5015. + registerPOD(joytype);
  5016. + registerPOD(stick);
  5017. + registerPOD(last_write);
  5018. + registerPOD(write_active);
  5019. + registerPOD(swap34);
  5020. + registerPOD(button_wrapping_enabled);
  5021. + registerPOD(autofire);
  5022. + }
  5023. +} dummy;
  5024. +}
  5025. \ No newline at end of file
  5026. Index: src/hardware/keyboard.cpp
  5027. ===================================================================
  5028. --- src/hardware/keyboard.cpp (revision 4176)
  5029. +++ src/hardware/keyboard.cpp (working copy)
  5030. @@ -25,6 +25,8 @@
  5031. #include "mixer.h"
  5032. #include "timer.h"
  5033.  
  5034. +#include "../save_state.h"
  5035. +
  5036. #define KEYBUFSIZE 32
  5037. #define KEYDELAY 0.300f //Considering 20-30 khz serial clock and 11 bits/char
  5038.  
  5039. @@ -392,3 +394,32 @@
  5040. keyb.repeat.wait=0;
  5041. KEYBOARD_ClrBuffer();
  5042. }
  5043. +
  5044. +//save state support
  5045. +void *KEYBOARD_TransferBuffer_PIC_Event = (void*)KEYBOARD_TransferBuffer;
  5046. +void *KEYBOARD_TickHandler_PIC_Timer = (void*)KEYBOARD_TickHandler;
  5047. +
  5048. +namespace
  5049. +{
  5050. +class SerializeKeyboard : public SerializeGlobalPOD
  5051. +{
  5052. +public:
  5053. + SerializeKeyboard() : SerializeGlobalPOD("Keyboard")
  5054. + {
  5055. + registerPOD(keyb.buffer);
  5056. + registerPOD(keyb.used);
  5057. + registerPOD(keyb.pos);
  5058. + registerPOD(keyb.repeat.key);
  5059. + registerPOD(keyb.repeat.wait);
  5060. + registerPOD(keyb.repeat.pause);
  5061. + registerPOD(keyb.repeat.rate);
  5062. + registerPOD(keyb.command);
  5063. + registerPOD(keyb.p60data);
  5064. + registerPOD(keyb.p60changed);
  5065. + registerPOD(keyb.active);
  5066. + registerPOD(keyb.scanning);
  5067. + registerPOD(keyb.scheduled);
  5068. + registerPOD(port_61_data);
  5069. + }
  5070. +} dummy;
  5071. +}
  5072. \ No newline at end of file
  5073. Index: src/hardware/mame/emu.h
  5074. ===================================================================
  5075. --- src/hardware/mame/emu.h (revision 4176)
  5076. +++ src/hardware/mame/emu.h (working copy)
  5077. @@ -22,6 +22,9 @@
  5078. #define M_PI 3.14159265358979323846
  5079. #endif
  5080.  
  5081. +#include "../../save_state.h"
  5082. +#include <sstream>
  5083. +
  5084. typedef Bit16s stream_sample_t;
  5085.  
  5086. typedef Bit8u u8;
  5087. @@ -123,6 +126,12 @@
  5088. device_t(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 _clock) : clockRate( _clock ) {
  5089. }
  5090.  
  5091. + void SaveState( std::ostream& stream ) {
  5092. + WRITE_POD( &clockRate, clockRate );
  5093. + }
  5094. + void LoadState( std::istream& stream ) {
  5095. + READ_POD( &clockRate, clockRate );
  5096. + }
  5097. };
  5098.  
  5099.  
  5100. Index: src/hardware/mame/fmopl.cpp
  5101. ===================================================================
  5102. --- src/hardware/mame/fmopl.cpp (revision 4176)
  5103. +++ src/hardware/mame/fmopl.cpp (working copy)
  5104. @@ -73,8 +73,6 @@
  5105. #include "ymdeltat.h"
  5106. #include "fmopl.h"
  5107.  
  5108. -
  5109. -
  5110. /* output final shift */
  5111. #if (OPL_SAMPLE_BITS==16)
  5112. #define FINAL_SH (0)
  5113. @@ -2174,6 +2172,162 @@
  5114. return OPLWrite(YM3812, a, v);
  5115. }
  5116.  
  5117. +void SaveState_Channel(OPL_CH *CH, std::ostream& stream) {
  5118. + int slot, ch;
  5119. +
  5120. + for( ch=0 ; ch < 9 ; ch++, CH++ ) {
  5121. + /* channel */
  5122. + WRITE_POD( &CH->block_fnum, CH->block_fnum );
  5123. + WRITE_POD( &CH->kcode, CH->kcode );
  5124. + /* slots */
  5125. + for( slot=0 ; slot < 2 ; slot++ ) {
  5126. + OPL_SLOT *SLOT = &CH->SLOT[slot];
  5127. +
  5128. + WRITE_POD( &SLOT->ar, SLOT->ar );
  5129. + WRITE_POD( &SLOT->dr, SLOT->dr );
  5130. + WRITE_POD( &SLOT->rr, SLOT->rr );
  5131. + WRITE_POD( &SLOT->KSR, SLOT->KSR );
  5132. + WRITE_POD( &SLOT->ksl, SLOT->ksl );
  5133. + WRITE_POD( &SLOT->mul, SLOT->mul );
  5134. +
  5135. + WRITE_POD( &SLOT->Cnt, SLOT->Cnt );
  5136. + WRITE_POD( &SLOT->FB, SLOT->FB );
  5137. + WRITE_POD( &SLOT->op1_out, SLOT->op1_out );
  5138. + WRITE_POD( &SLOT->CON, SLOT->CON );
  5139. +
  5140. + WRITE_POD( &SLOT->eg_type, SLOT->eg_type );
  5141. + WRITE_POD( &SLOT->state, SLOT->state );
  5142. + WRITE_POD( &SLOT->TL, SLOT->TL );
  5143. + WRITE_POD( &SLOT->volume, SLOT->volume );
  5144. + WRITE_POD( &SLOT->sl, SLOT->sl );
  5145. + WRITE_POD( &SLOT->key, SLOT->key );
  5146. +
  5147. + WRITE_POD( &SLOT->AMmask, SLOT->AMmask );
  5148. + WRITE_POD( &SLOT->vib, SLOT->vib );
  5149. +
  5150. + WRITE_POD( &SLOT->wavetable, SLOT->wavetable );
  5151. + }
  5152. + }
  5153. +}
  5154. +
  5155. +void LoadState_Channel(OPL_CH *CH, std::istream& stream) {
  5156. + int slot, ch;
  5157. +
  5158. + for( ch=0 ; ch < 9 ; ch++, CH++ ) {
  5159. + /* channel */
  5160. + READ_POD( &CH->block_fnum, CH->block_fnum );
  5161. + READ_POD( &CH->kcode, CH->kcode );
  5162. + /* slots */
  5163. + for( slot=0 ; slot < 2 ; slot++ ) {
  5164. + OPL_SLOT *SLOT = &CH->SLOT[slot];
  5165. +
  5166. + READ_POD( &SLOT->ar, SLOT->ar );
  5167. + READ_POD( &SLOT->dr, SLOT->dr );
  5168. + READ_POD( &SLOT->rr, SLOT->rr );
  5169. + READ_POD( &SLOT->KSR, SLOT->KSR );
  5170. + READ_POD( &SLOT->ksl, SLOT->ksl );
  5171. + READ_POD( &SLOT->mul, SLOT->mul );
  5172. +
  5173. + READ_POD( &SLOT->Cnt, SLOT->Cnt );
  5174. + READ_POD( &SLOT->FB, SLOT->FB );
  5175. + READ_POD( &SLOT->op1_out, SLOT->op1_out );
  5176. + READ_POD( &SLOT->CON, SLOT->CON );
  5177. +
  5178. + READ_POD( &SLOT->eg_type, SLOT->eg_type );
  5179. + READ_POD( &SLOT->state, SLOT->state );
  5180. + READ_POD( &SLOT->TL, SLOT->TL );
  5181. + READ_POD( &SLOT->volume, SLOT->volume );
  5182. + READ_POD( &SLOT->sl, SLOT->sl );
  5183. + READ_POD( &SLOT->key, SLOT->key );
  5184. +
  5185. + READ_POD( &SLOT->AMmask, SLOT->AMmask );
  5186. + READ_POD( &SLOT->vib, SLOT->vib );
  5187. +
  5188. + READ_POD( &SLOT->wavetable, SLOT->wavetable );
  5189. + }
  5190. + }
  5191. +}
  5192. +
  5193. +// save state support
  5194. +void FMOPL_SaveState(void *chip, std::ostream& stream ) {
  5195. + FM_OPL *OPL = (FM_OPL *)chip;
  5196. +
  5197. + SaveState_Channel(OPL->P_CH, stream);
  5198. +
  5199. + WRITE_POD(&OPL->eg_cnt, OPL->eg_cnt);
  5200. + WRITE_POD(&OPL->eg_timer, OPL->eg_timer);
  5201. +
  5202. + WRITE_POD(&OPL->rhythm, OPL->rhythm);
  5203. +
  5204. + WRITE_POD(&OPL->lfo_am_depth, OPL->lfo_am_depth);
  5205. + WRITE_POD(&OPL->lfo_pm_depth_range, OPL->lfo_pm_depth_range);
  5206. + WRITE_POD(&OPL->lfo_am_cnt, OPL->lfo_am_cnt);
  5207. + WRITE_POD(&OPL->lfo_pm_cnt, OPL->lfo_pm_cnt);
  5208. +
  5209. + WRITE_POD(&OPL->noise_rng, OPL->noise_rng);
  5210. + WRITE_POD(&OPL->noise_p, OPL->noise_p);
  5211. +
  5212. + if( OPL->type & OPL_TYPE_WAVESEL ) {
  5213. + WRITE_POD(&OPL->wavesel, OPL->wavesel);
  5214. + }
  5215. +
  5216. + WRITE_POD(&OPL->T, OPL->T);
  5217. + WRITE_POD(&OPL->st, OPL->st);
  5218. +
  5219. +#if BUILD_Y8950
  5220. + //ToDo - Bruenor
  5221. + /*if ( (OPL->type & OPL_TYPE_ADPCM) && (OPL->deltat) ) {
  5222. + // OPL->deltat->savestate(device);
  5223. + }
  5224. +
  5225. + if ( OPL->type & OPL_TYPE_IO ) {
  5226. + // device->save_item(NAME(OPL->portDirection));
  5227. + // device->save_item(NAME(OPL->portLatch));
  5228. + }*/
  5229. +#endif
  5230. +
  5231. + WRITE_POD(&OPL->address, OPL->address);
  5232. + WRITE_POD(&OPL->status, OPL->status);
  5233. + WRITE_POD(&OPL->statusmask, OPL->statusmask);
  5234. + WRITE_POD(&OPL->mode, OPL->mode);
  5235. +}
  5236. +
  5237. +void FMOPL_LoadState(void *chip, std::istream& stream ) {
  5238. + FM_OPL *OPL = (FM_OPL *)chip;
  5239. +
  5240. + LoadState_Channel(OPL->P_CH, stream);
  5241. +
  5242. + READ_POD(&OPL->eg_cnt, OPL->eg_cnt);
  5243. + READ_POD(&OPL->eg_timer, OPL->eg_timer);
  5244. +
  5245. + READ_POD(&OPL->rhythm, OPL->rhythm);
  5246. +
  5247. + READ_POD(&OPL->lfo_am_depth, OPL->lfo_am_depth);
  5248. + READ_POD(&OPL->lfo_pm_depth_range, OPL->lfo_pm_depth_range);
  5249. + READ_POD(&OPL->lfo_am_cnt, OPL->lfo_am_cnt);
  5250. + READ_POD(&OPL->lfo_pm_cnt, OPL->lfo_pm_cnt);
  5251. +
  5252. + READ_POD(&OPL->noise_rng, OPL->noise_rng);
  5253. + READ_POD(&OPL->noise_p, OPL->noise_p);
  5254. +
  5255. + if( OPL->type & OPL_TYPE_WAVESEL ) {
  5256. + READ_POD(&OPL->wavesel, OPL->wavesel);
  5257. + }
  5258. +
  5259. + READ_POD(&OPL->T, OPL->T);
  5260. + READ_POD(&OPL->st, OPL->st);
  5261. +
  5262. +#if BUILD_Y8950
  5263. + //ToDo - Bruenor
  5264. +#endif
  5265. +
  5266. + READ_POD(&OPL->address, OPL->address);
  5267. + READ_POD(&OPL->status, OPL->status);
  5268. + READ_POD(&OPL->statusmask, OPL->statusmask);
  5269. + READ_POD(&OPL->mode, OPL->mode);
  5270. +}
  5271. +
  5272. +
  5273. unsigned char ym3812_read(void *chip, int a)
  5274. {
  5275. FM_OPL *YM3812 = (FM_OPL *)chip;
  5276. Index: src/hardware/mame/fmopl.h
  5277. ===================================================================
  5278. --- src/hardware/mame/fmopl.h (revision 4176)
  5279. +++ src/hardware/mame/fmopl.h (working copy)
  5280. @@ -36,6 +36,8 @@
  5281. typedef void (*OPL_PORTHANDLER_W)(device_t *device,unsigned char data);
  5282. typedef unsigned char (*OPL_PORTHANDLER_R)(device_t *device);
  5283.  
  5284. +#include "../../save_state.h"
  5285. +#include <sstream>
  5286.  
  5287. #if BUILD_YM3812
  5288.  
  5289. @@ -44,6 +46,8 @@
  5290. void ym3812_shutdown(void *chip);
  5291. void ym3812_reset_chip(void *chip);
  5292. int ym3812_write(void *chip, int a, int v);
  5293. +void FMOPL_SaveState( void *chip, std::ostream& stream );
  5294. +void FMOPL_LoadState( void *chip, std::istream& stream );
  5295. unsigned char ym3812_read(void *chip, int a);
  5296. int ym3812_timer_over(void *chip, int c);
  5297. void ym3812_update_one(void *chip, OPLSAMPLE *buffer, int length);
  5298. Index: src/hardware/mame/saa1099.cpp
  5299. ===================================================================
  5300. --- src/hardware/mame/saa1099.cpp (revision 4176)
  5301. +++ src/hardware/mame/saa1099.cpp (working copy)
  5302. @@ -357,7 +357,50 @@
  5303. }
  5304. }
  5305.  
  5306. +void saa1099_device::SaveState( std::ostream& stream )
  5307. +{
  5308. + // - pure data
  5309. + device_t::SaveState(stream);
  5310.  
  5311. + WRITE_POD( &m_noise_params, m_noise_params );
  5312. + WRITE_POD( &m_env_enable, m_env_enable );
  5313. + WRITE_POD( &m_env_reverse_right, m_env_reverse_right );
  5314. + WRITE_POD( &m_env_mode, m_env_mode );
  5315. + WRITE_POD( &m_env_bits, m_env_bits );
  5316. + WRITE_POD( &m_env_clock, m_env_clock );
  5317. + WRITE_POD( &m_env_step, m_env_step );
  5318. + WRITE_POD( &m_all_ch_enable, m_all_ch_enable );
  5319. + WRITE_POD( &m_sync_state, m_sync_state );
  5320. + WRITE_POD( &m_selected_reg, m_selected_reg );
  5321. + WRITE_POD( &m_channels, m_channels );
  5322. + WRITE_POD( &m_noise, m_noise );
  5323. + WRITE_POD( &m_sample_rate, m_sample_rate );
  5324. + WRITE_POD( &m_master_clock, m_master_clock );
  5325. +}
  5326. +
  5327. +
  5328. +void saa1099_device::LoadState( std::istream& stream )
  5329. +{
  5330. + // - pure data
  5331. + device_t::LoadState(stream);
  5332. +
  5333. + READ_POD( &m_noise_params, m_noise_params );
  5334. + READ_POD( &m_env_enable, m_env_enable );
  5335. + READ_POD( &m_env_reverse_right, m_env_reverse_right );
  5336. + READ_POD( &m_env_mode, m_env_mode );
  5337. + READ_POD( &m_env_bits, m_env_bits );
  5338. + READ_POD( &m_env_clock, m_env_clock );
  5339. + READ_POD( &m_env_step, m_env_step );
  5340. + READ_POD( &m_all_ch_enable, m_all_ch_enable );
  5341. + READ_POD( &m_sync_state, m_sync_state );
  5342. + READ_POD( &m_selected_reg, m_selected_reg );
  5343. + READ_POD( &m_channels, m_channels );
  5344. + READ_POD( &m_noise, m_noise );
  5345. + READ_POD( &m_sample_rate, m_sample_rate );
  5346. + READ_POD( &m_master_clock, m_master_clock );
  5347. +}
  5348. +
  5349. +
  5350. WRITE8_MEMBER( saa1099_device::control_w )
  5351. {
  5352. if ((data & 0xff) > 0x1c)
  5353. Index: src/hardware/mame/saa1099.h
  5354. ===================================================================
  5355. --- src/hardware/mame/saa1099.h (revision 4176)
  5356. +++ src/hardware/mame/saa1099.h (working copy)
  5357. @@ -23,6 +23,9 @@
  5358. // TYPE DEFINITIONS
  5359. //**************************************************************************
  5360.  
  5361. +#include "../../save_state.h"
  5362. +#include <sstream>
  5363. +
  5364. //Container class for int that just initalizes to 0
  5365. class NullInt {
  5366. int value;
  5367. @@ -60,6 +63,8 @@
  5368. // sound stream update overrides
  5369. virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
  5370.  
  5371. + void SaveState( std::ostream& stream );
  5372. + void LoadState( std::istream& stream );
  5373. private:
  5374. struct saa1099_channel
  5375. {
  5376. Index: src/hardware/mame/sn76496.cpp
  5377. ===================================================================
  5378. --- src/hardware/mame/sn76496.cpp (revision 4176)
  5379. +++ src/hardware/mame/sn76496.cpp (working copy)
  5380. @@ -482,6 +482,47 @@
  5381. rate_counter = 0;
  5382. }
  5383.  
  5384. +void sn76496_base_device::SaveState( std::ostream& stream ) {
  5385. + WRITE_POD(&m_vol_table, m_vol_table);
  5386. + WRITE_POD(&m_register, m_register);
  5387. + WRITE_POD(&m_last_register, m_last_register);
  5388. + WRITE_POD(&m_volume, m_volume);
  5389. + WRITE_POD(&m_RNG, m_RNG);
  5390. + //WRITE_POD(&m_clock_divider, m_clock_divider);
  5391. + WRITE_POD(&m_current_clock, m_current_clock);
  5392. + //WRITE_POD(&m_feedback_mask, m_feedback_mask);
  5393. + //WRITE_POD(&m_whitenoise_tap1, m_whitenoise_tap1);
  5394. + //WRITE_POD(&m_whitenoise_tap2, m_whitenoise_tap2);
  5395. + //WRITE_POD(&m_negate, m_negate);
  5396. + //WRITE_POD(&m_stereo, m_stereo);
  5397. + WRITE_POD(&m_stereo_mask, m_stereo_mask);
  5398. + WRITE_POD(&m_period, m_period);
  5399. + WRITE_POD(&m_count, m_count);
  5400. + WRITE_POD(&m_output, m_output);
  5401. + WRITE_POD(&m_cycles_to_ready, m_cycles_to_ready);
  5402. + //WRITE_POD(&m_sega_style_psg, m_sega_style_psg);
  5403. +}
  5404. +void sn76496_base_device::LoadState( std::istream& stream ) {
  5405. + READ_POD(&m_vol_table, m_vol_table);
  5406. + READ_POD(&m_register, m_register);
  5407. + READ_POD(&m_last_register, m_last_register);
  5408. + READ_POD(&m_volume, m_volume);
  5409. + READ_POD(&m_RNG, m_RNG);
  5410. + //READ_POD(&m_clock_divider, m_clock_divider);
  5411. + READ_POD(&m_current_clock, m_current_clock);
  5412. + //READ_POD(&m_feedback_mask, m_feedback_mask);
  5413. + //READ_POD(&m_whitenoise_tap1, m_whitenoise_tap1);
  5414. + //READ_POD(&m_whitenoise_tap2, m_whitenoise_tap2);
  5415. + //READ_POD(&m_negate, m_negate);
  5416. + //READ_POD(&m_stereo, m_stereo);
  5417. + READ_POD(&m_stereo_mask, m_stereo_mask);
  5418. + READ_POD(&m_period, m_period);
  5419. + READ_POD(&m_count, m_count);
  5420. + READ_POD(&m_output, m_output);
  5421. + READ_POD(&m_cycles_to_ready, m_cycles_to_ready);
  5422. + //READ_POD(&m_sega_style_psg, m_sega_style_psg);
  5423. +}
  5424. +
  5425. void sn76496_base_device::register_for_save_states()
  5426. {
  5427. save_item(NAME(m_vol_table));
  5428. Index: src/hardware/mame/sn76496.h
  5429. ===================================================================
  5430. --- src/hardware/mame/sn76496.h (revision 4176)
  5431. +++ src/hardware/mame/sn76496.h (working copy)
  5432. @@ -26,6 +26,9 @@
  5433.  
  5434. #endif
  5435.  
  5436. +#include "../../save_state.h"
  5437. +#include <sstream>
  5438. +
  5439. class sn76496_base_device : public device_t, public device_sound_interface
  5440. {
  5441. public:
  5442. @@ -39,6 +42,9 @@
  5443. // auto ready_cb() { return m_ready_handler.bind(); }
  5444.  
  5445. void convert_samplerate(int32_t target_rate);
  5446. +
  5447. + void SaveState( std::ostream& stream );
  5448. + void LoadState( std::istream& stream );
  5449. protected:
  5450. sn76496_base_device(
  5451. const machine_config &mconfig,
  5452. Index: src/hardware/mame/ymf262.cpp
  5453. ===================================================================
  5454. --- src/hardware/mame/ymf262.cpp (revision 4176)
  5455. +++ src/hardware/mame/ymf262.cpp (working copy)
  5456. @@ -2558,6 +2558,130 @@
  5457. return OPL3Write((OPL3 *)chip, a, v);
  5458. }
  5459.  
  5460. +void SaveState_Channel(OPL3_CH *channel, std::ostream& stream) {
  5461. + WRITE_POD( &channel->block_fnum, channel->block_fnum );
  5462. + WRITE_POD( &channel->fc, channel->fc );
  5463. + WRITE_POD( &channel->ksl_base, channel->ksl_base );
  5464. + WRITE_POD( &channel->kcode, channel->kcode );
  5465. + WRITE_POD( &channel->extended, channel->extended );
  5466. +}
  5467. +
  5468. +void LoadState_Channel(OPL3_CH *channel, std::istream& stream) {
  5469. + READ_POD( &channel->block_fnum, channel->block_fnum );
  5470. + READ_POD( &channel->fc, channel->fc );
  5471. + READ_POD( &channel->ksl_base, channel->ksl_base );
  5472. + READ_POD( &channel->kcode, channel->kcode );
  5473. + READ_POD( &channel->extended, channel->extended );
  5474. +}
  5475. +
  5476. +void SaveState_Slot(OPL3_SLOT *slot, std::ostream& stream) {
  5477. + WRITE_POD( &slot->ar, slot->ar );
  5478. + WRITE_POD( &slot->dr, slot->dr );
  5479. + WRITE_POD( &slot->rr, slot->rr );
  5480. + WRITE_POD( &slot->KSR, slot->KSR );
  5481. + WRITE_POD( &slot->ksl, slot->ksl );
  5482. + WRITE_POD( &slot->ksr, slot->ksr );
  5483. + WRITE_POD( &slot->mul, slot->mul );
  5484. +
  5485. + WRITE_POD( &slot->Cnt, slot->Cnt );
  5486. + WRITE_POD( &slot->Incr, slot->Incr );
  5487. + WRITE_POD( &slot->FB, slot->FB );
  5488. + WRITE_POD( &slot->conn_enum, slot->conn_enum );
  5489. + WRITE_POD( &slot->op1_out, slot->op1_out );
  5490. + WRITE_POD( &slot->CON, slot->CON );
  5491. +
  5492. + WRITE_POD( &slot->eg_type, slot->eg_type );
  5493. + WRITE_POD( &slot->state, slot->state );
  5494. + WRITE_POD( &slot->TL, slot->TL );
  5495. + WRITE_POD( &slot->TLL, slot->TLL );
  5496. + WRITE_POD( &slot->volume, slot->volume );
  5497. + WRITE_POD( &slot->sl, slot->sl );
  5498. +
  5499. + WRITE_POD( &slot->eg_m_ar, slot->eg_m_ar );
  5500. + WRITE_POD( &slot->eg_sh_ar, slot->eg_sh_ar );
  5501. + WRITE_POD( &slot->eg_sel_ar, slot->eg_sel_ar );
  5502. + WRITE_POD( &slot->eg_m_dr, slot->eg_m_dr );
  5503. + WRITE_POD( &slot->eg_sh_dr, slot->eg_sh_dr );
  5504. + WRITE_POD( &slot->eg_sel_dr, slot->eg_sel_dr );
  5505. + WRITE_POD( &slot->eg_m_rr, slot->eg_m_rr );
  5506. + WRITE_POD( &slot->eg_sh_rr, slot->eg_sh_rr );
  5507. + WRITE_POD( &slot->eg_sel_rr, slot->eg_sel_rr );
  5508. +
  5509. + WRITE_POD( &slot->key, slot->key );
  5510. +
  5511. + WRITE_POD( &slot->AMmask, slot->AMmask );
  5512. + WRITE_POD( &slot->vib, slot->vib );
  5513. +
  5514. + WRITE_POD( &slot->waveform_number, slot->waveform_number );
  5515. + WRITE_POD( &slot->wavetable, slot->wavetable );
  5516. +}
  5517. +
  5518. +void LoadState_Slot(OPL3_SLOT *slot, std::istream& stream) {
  5519. + READ_POD( &slot->ar, slot->ar );
  5520. + READ_POD( &slot->dr, slot->dr );
  5521. + READ_POD( &slot->rr, slot->rr );
  5522. + READ_POD( &slot->KSR, slot->KSR );
  5523. + READ_POD( &slot->ksl, slot->ksl );
  5524. + READ_POD( &slot->ksr, slot->ksr );
  5525. + READ_POD( &slot->mul, slot->mul );
  5526. +
  5527. + READ_POD( &slot->Cnt, slot->Cnt );
  5528. + READ_POD( &slot->Incr, slot->Incr );
  5529. + READ_POD( &slot->FB, slot->FB );
  5530. + READ_POD( &slot->conn_enum, slot->conn_enum );
  5531. + READ_POD( &slot->op1_out, slot->op1_out );
  5532. + READ_POD( &slot->CON, slot->CON );
  5533. +
  5534. + READ_POD( &slot->eg_type, slot->eg_type );
  5535. + READ_POD( &slot->state, slot->state );
  5536. + READ_POD( &slot->TL, slot->TL );
  5537. + READ_POD( &slot->TLL, slot->TLL );
  5538. + READ_POD( &slot->volume, slot->volume );
  5539. + READ_POD( &slot->sl, slot->sl );
  5540. +
  5541. + READ_POD( &slot->eg_m_ar, slot->eg_m_ar );
  5542. + READ_POD( &slot->eg_sh_ar, slot->eg_sh_ar );
  5543. + READ_POD( &slot->eg_sel_ar, slot->eg_sel_ar );
  5544. + READ_POD( &slot->eg_m_dr, slot->eg_m_dr );
  5545. + READ_POD( &slot->eg_sh_dr, slot->eg_sh_dr );
  5546. + READ_POD( &slot->eg_sel_dr, slot->eg_sel_dr );
  5547. + READ_POD( &slot->eg_m_rr, slot->eg_m_rr );
  5548. + READ_POD( &slot->eg_sh_rr, slot->eg_sh_rr );
  5549. + READ_POD( &slot->eg_sel_rr, slot->eg_sel_rr );
  5550. +
  5551. + READ_POD( &slot->key, slot->key );
  5552. +
  5553. + READ_POD( &slot->AMmask, slot->AMmask );
  5554. + READ_POD( &slot->vib, slot->vib );
  5555. +
  5556. + READ_POD( &slot->waveform_number, slot->waveform_number );
  5557. + READ_POD( &slot->wavetable, slot->wavetable );
  5558. +}
  5559. +
  5560. +void YMF_SaveState( void *chip, std::ostream& stream ) {
  5561. + for (int ch=0; ch<18; ch++) {
  5562. + OPL3_CH *channel = &((OPL3 *)chip)->P_CH[ch];
  5563. +
  5564. + SaveState_Channel(channel, stream);
  5565. +
  5566. + for (int sl=0; sl<2; sl++) {
  5567. + SaveState_Slot(&channel->SLOT[sl], stream);
  5568. + }
  5569. + }
  5570. +}
  5571. +
  5572. +void YMF_LoadState( void *chip, std::istream& stream ) {
  5573. + for (int ch=0; ch<18; ch++) {
  5574. + OPL3_CH *channel = &((OPL3 *)chip)->P_CH[ch];
  5575. +
  5576. + LoadState_Channel(channel, stream);
  5577. +
  5578. + for (int sl=0; sl<2; sl++) {
  5579. + LoadState_Slot(&channel->SLOT[sl], stream);
  5580. + }
  5581. + }
  5582. +}
  5583. +
  5584. unsigned char ymf262_read(void *chip, int a)
  5585. {
  5586. /* Note on status register: */
  5587. Index: src/hardware/mame/ymf262.h
  5588. ===================================================================
  5589. --- src/hardware/mame/ymf262.h (revision 4176)
  5590. +++ src/hardware/mame/ymf262.h (working copy)
  5591. @@ -28,6 +28,8 @@
  5592. void ymf262_shutdown(void *chip);
  5593. void ymf262_reset_chip(void *chip);
  5594. int ymf262_write(void *chip, int a, int v);
  5595. +void YMF_SaveState( void *chip, std::ostream& stream );
  5596. +void YMF_LoadState( void *chip, std::istream& stream );
  5597. unsigned char ymf262_read(void *chip, int a);
  5598. int ymf262_timer_over(void *chip, int c);
  5599. void ymf262_update_one(void *chip, OPL3SAMPLE **buffers, int length);
  5600. Index: src/hardware/memory.cpp
  5601. ===================================================================
  5602. --- src/hardware/memory.cpp (revision 4176)
  5603. +++ src/hardware/memory.cpp (working copy)
  5604. @@ -24,6 +24,8 @@
  5605. #include "paging.h"
  5606. #include "regs.h"
  5607.  
  5608. +#include "../save_state.h"
  5609. +
  5610. #include <string.h>
  5611.  
  5612. #define PAGES_IN_BLOCK ((1024*1024)/MEM_PAGE_SIZE)
  5613. @@ -612,3 +614,121 @@
  5614. test = new MEMORY(sec);
  5615. sec->AddDestroyFunction(&MEM_ShutDown);
  5616. }
  5617. +
  5618. +//save state support
  5619. +extern void* VGA_PageHandler_Func[16];
  5620. +
  5621. +void *Memory_PageHandler_table[] =
  5622. +{
  5623. + NULL,
  5624. + &ram_page_handler,
  5625. + &rom_page_handler,
  5626. +
  5627. + VGA_PageHandler_Func[0],
  5628. + VGA_PageHandler_Func[1],
  5629. + VGA_PageHandler_Func[2],
  5630. + VGA_PageHandler_Func[3],
  5631. + VGA_PageHandler_Func[4],
  5632. + VGA_PageHandler_Func[5],
  5633. + VGA_PageHandler_Func[6],
  5634. + VGA_PageHandler_Func[7],
  5635. + VGA_PageHandler_Func[8],
  5636. + VGA_PageHandler_Func[9],
  5637. + VGA_PageHandler_Func[10],
  5638. + VGA_PageHandler_Func[11],
  5639. + VGA_PageHandler_Func[12],
  5640. + VGA_PageHandler_Func[13],
  5641. + VGA_PageHandler_Func[14],
  5642. + VGA_PageHandler_Func[15],
  5643. +};
  5644. +
  5645. +
  5646. +namespace
  5647. +{
  5648. +class SerializeMemory : public SerializeGlobalPOD
  5649. +{
  5650. +public:
  5651. + SerializeMemory() : SerializeGlobalPOD("Memory")
  5652. + {}
  5653. +
  5654. +private:
  5655. + virtual void getBytes(std::ostream& stream)
  5656. + {
  5657. + Bit8u pagehandler_idx[0x10000];
  5658. + int size_table;
  5659. +
  5660. +
  5661. + // assume 256MB max memory
  5662. + size_table = sizeof(Memory_PageHandler_table) / sizeof(void *);
  5663. + for( int lcv=0; lcv<memory.pages; lcv++ ) {
  5664. + pagehandler_idx[lcv] = 0xff;
  5665. +
  5666. + for( int lcv2=0; lcv2<size_table; lcv2++ ) {
  5667. + if( memory.phandlers[lcv] == Memory_PageHandler_table[lcv2] ) {
  5668. + pagehandler_idx[lcv] = lcv2;
  5669. + break;
  5670. + }
  5671. + }
  5672. + }
  5673. +
  5674. + //*******************************************
  5675. + //*******************************************
  5676. +
  5677. + SerializeGlobalPOD::getBytes(stream);
  5678. +
  5679. + // - near-pure data
  5680. + WRITE_POD( &memory, memory );
  5681. +
  5682. + // - static 'new' ptr
  5683. + WRITE_POD_SIZE( MemBase, memory.pages*4096 );
  5684. +
  5685. + //***********************************************
  5686. + //***********************************************
  5687. +
  5688. + WRITE_POD_SIZE( memory.mhandles, sizeof(MemHandle) * memory.pages );
  5689. + WRITE_POD( &pagehandler_idx, pagehandler_idx );
  5690. + }
  5691. +
  5692. + virtual void setBytes(std::istream& stream)
  5693. + {
  5694. + Bit8u pagehandler_idx[0x10000];
  5695. + void *old_ptrs[4];
  5696. +
  5697. + old_ptrs[0] = (void *) memory.phandlers;
  5698. + old_ptrs[1] = (void *) memory.mhandles;
  5699. + old_ptrs[2] = (void *) memory.lfb.handler;
  5700. + old_ptrs[3] = (void *) memory.lfb.mmiohandler;
  5701. +
  5702. + //***********************************************
  5703. + //***********************************************
  5704. +
  5705. + SerializeGlobalPOD::setBytes(stream);
  5706. +
  5707. +
  5708. + // - near-pure data
  5709. + READ_POD( &memory, memory );
  5710. +
  5711. + // - static 'new' ptr
  5712. + READ_POD_SIZE( MemBase, memory.pages*4096 );
  5713. +
  5714. + //***********************************************
  5715. + //***********************************************
  5716. +
  5717. + memory.phandlers = (PageHandler **) old_ptrs[0];
  5718. + memory.mhandles = (MemHandle *) old_ptrs[1];
  5719. + memory.lfb.handler = (PageHandler *) old_ptrs[2];
  5720. + memory.lfb.mmiohandler = (PageHandler *) old_ptrs[3];
  5721. +
  5722. +
  5723. + READ_POD_SIZE( memory.mhandles, sizeof(MemHandle) * memory.pages );
  5724. + READ_POD( &pagehandler_idx, pagehandler_idx );
  5725. +
  5726. +
  5727. + for( int lcv=0; lcv<memory.pages; lcv++ ) {
  5728. + if( pagehandler_idx[lcv] == 0xff ) continue;
  5729. +
  5730. + memory.phandlers[lcv] = (PageHandler *) Memory_PageHandler_table[ pagehandler_idx[lcv] ];
  5731. + }
  5732. + }
  5733. +} dummy;
  5734. +}
  5735. Index: src/hardware/mixer.cpp
  5736. ===================================================================
  5737. --- src/hardware/mixer.cpp (revision 4176)
  5738. +++ src/hardware/mixer.cpp (working copy)
  5739. @@ -49,6 +49,8 @@
  5740. #include "programs.h"
  5741. #include "midi.h"
  5742.  
  5743. +#include "../save_state.h"
  5744. +
  5745. #define MIXER_SSIZE 4
  5746.  
  5747. //#define MIXER_SHIFT 14
  5748. @@ -717,3 +719,108 @@
  5749. mixer.needed=mixer.min_needed+1;
  5750. PROGRAMS_MakeFile("MIXER.COM",MIXER_ProgramStart);
  5751. }
  5752. +
  5753. +// save state support
  5754. +void *MIXER_Mix_NoSound_PIC_Timer = (void*)MIXER_Mix_NoSound;
  5755. +void *MIXER_Mix_PIC_Timer = (void*)MIXER_Mix;
  5756. +
  5757. +
  5758. +void MixerChannel::SaveState( std::ostream& stream )
  5759. +{
  5760. + // - pure data
  5761. + WRITE_POD( &volmain, volmain );
  5762. + WRITE_POD( &scale, scale );
  5763. + WRITE_POD( &volmul, volmul );
  5764. + WRITE_POD( &freq_add, freq_add );
  5765. + WRITE_POD( &enabled, enabled );
  5766. +}
  5767. +
  5768. +
  5769. +void MixerChannel::LoadState( std::istream& stream )
  5770. +{
  5771. + // - pure data
  5772. + READ_POD( &volmain, volmain );
  5773. + READ_POD( &scale, scale );
  5774. + READ_POD( &volmul, volmul );
  5775. + READ_POD( &freq_add, freq_add );
  5776. + READ_POD( &enabled, enabled );
  5777. +
  5778. + //********************************************
  5779. + //********************************************
  5780. + //********************************************
  5781. +
  5782. + // reset mixer channel (system data)
  5783. + done = 0;
  5784. + needed = 0;
  5785. +}
  5786. +
  5787. +extern void POD_Save_Adlib(std::ostream& stream);
  5788. +extern void POD_Save_Disney(std::ostream& stream);
  5789. +extern void POD_Save_Gameblaster(std::ostream& stream);
  5790. +extern void POD_Save_GUS(std::ostream& stream);
  5791. +extern void POD_Save_MPU401(std::ostream& stream);
  5792. +extern void POD_Save_PCSpeaker(std::ostream& stream);
  5793. +extern void POD_Save_Sblaster(std::ostream& stream);
  5794. +extern void POD_Save_Tandy_Sound(std::ostream& stream);
  5795. +extern void POD_Load_Adlib(std::istream& stream);
  5796. +extern void POD_Load_Disney(std::istream& stream);
  5797. +extern void POD_Load_Gameblaster(std::istream& stream);
  5798. +extern void POD_Load_GUS(std::istream& stream);
  5799. +extern void POD_Load_MPU401(std::istream& stream);
  5800. +extern void POD_Load_PCSpeaker(std::istream& stream);
  5801. +extern void POD_Load_Sblaster(std::istream& stream);
  5802. +extern void POD_Load_Tandy_Sound(std::istream& stream);
  5803. +
  5804. +namespace
  5805. +{
  5806. +class SerializeMixer : public SerializeGlobalPOD
  5807. +{
  5808. +public:
  5809. + SerializeMixer() : SerializeGlobalPOD("Mixer")
  5810. + {}
  5811. +
  5812. +private:
  5813. + virtual void getBytes(std::ostream& stream)
  5814. + {
  5815. +
  5816. + //*************************************************
  5817. + //*************************************************
  5818. +
  5819. + SerializeGlobalPOD::getBytes(stream);
  5820. +
  5821. +
  5822. + POD_Save_Adlib(stream);
  5823. + POD_Save_Disney(stream);
  5824. + POD_Save_Gameblaster(stream);
  5825. + POD_Save_GUS(stream);
  5826. + POD_Save_MPU401(stream);
  5827. + POD_Save_PCSpeaker(stream);
  5828. + POD_Save_Sblaster(stream);
  5829. + POD_Save_Tandy_Sound(stream);
  5830. + }
  5831. +
  5832. + virtual void setBytes(std::istream& stream)
  5833. + {
  5834. +
  5835. + //*************************************************
  5836. + //*************************************************
  5837. +
  5838. + SerializeGlobalPOD::setBytes(stream);
  5839. +
  5840. +
  5841. + POD_Load_Adlib(stream);
  5842. + POD_Load_Disney(stream);
  5843. + POD_Load_Gameblaster(stream);
  5844. + POD_Load_GUS(stream);
  5845. + POD_Load_MPU401(stream);
  5846. + POD_Load_PCSpeaker(stream);
  5847. + POD_Load_Sblaster(stream);
  5848. + POD_Load_Tandy_Sound(stream);
  5849. +
  5850. + // reset mixer channel (system data)
  5851. + mixer.needed = 0;
  5852. + mixer.done = 0;
  5853. + }
  5854. +
  5855. +} dummy;
  5856. +}
  5857. \ No newline at end of file
  5858. Index: src/hardware/mpu401.cpp
  5859. ===================================================================
  5860. --- src/hardware/mpu401.cpp (revision 4176)
  5861. +++ src/hardware/mpu401.cpp (working copy)
  5862. @@ -25,6 +25,8 @@
  5863. #include "cpu.h"
  5864. #include "support.h"
  5865.  
  5866. +#include "../save_state.h"
  5867. +
  5868. void MIDI_RawOutByte(Bit8u data);
  5869. bool MIDI_Available(void);
  5870.  
  5871. @@ -674,3 +676,49 @@
  5872. test = new MPU401(sec);
  5873. sec->AddDestroyFunction(&MPU401_Destroy,true);
  5874. }
  5875. +
  5876. +// save state support
  5877. +void *MPU401_Event_PIC_Event = (void*)MPU401_Event;
  5878. +
  5879. +
  5880. +void POD_Save_MPU401( std::ostream& stream )
  5881. +{
  5882. + const char pod_name[32] = "MPU401";
  5883. +
  5884. + if( stream.fail() ) return;
  5885. + if( !test ) return;
  5886. +
  5887. +
  5888. + WRITE_POD( &pod_name, pod_name );
  5889. +
  5890. + //*******************************************
  5891. + //*******************************************
  5892. + //*******************************************
  5893. +
  5894. + // - pure data
  5895. + WRITE_POD( &mpu, mpu );
  5896. +}
  5897. +
  5898. +
  5899. +void POD_Load_MPU401( std::istream& stream )
  5900. +{
  5901. + char pod_name[32] = {0};
  5902. +
  5903. + if( stream.fail() ) return;
  5904. + if( !test ) return;
  5905. +
  5906. +
  5907. + // error checking
  5908. + READ_POD( &pod_name, pod_name );
  5909. + if( strcmp( pod_name, "MPU401" ) ) {
  5910. + stream.clear( std::istream::failbit | std::istream::badbit );
  5911. + return;
  5912. + }
  5913. +
  5914. + //************************************************
  5915. + //************************************************
  5916. + //************************************************
  5917. +
  5918. + // - pure data
  5919. + READ_POD( &mpu, mpu );
  5920. +}
  5921. \ No newline at end of file
  5922. Index: src/hardware/opl.cpp
  5923. ===================================================================
  5924. --- src/hardware/opl.cpp (revision 4176)
  5925. +++ src/hardware/opl.cpp (working copy)
  5926. @@ -30,6 +30,7 @@
  5927. #include "dosbox.h"
  5928. #include "opl.h"
  5929.  
  5930. +#include "../save_state.h"
  5931.  
  5932. static fltype recipsamp; // inverse of sampling rate
  5933. static Bit16s wavtable[WAVEPREC*3]; // wave form table
  5934. @@ -1459,3 +1460,116 @@
  5935.  
  5936. }
  5937. }
  5938. +
  5939. +// save state support
  5940. +void adlib_savestate( std::ostream& stream )
  5941. +{
  5942. + Bit32u cur_wform_idx[MAXOPERATORS];
  5943. +
  5944. +
  5945. + for( int lcv=0; lcv<MAXOPERATORS; lcv++ ) {
  5946. + cur_wform_idx[lcv] = ((Bitu) (op[lcv].cur_wform)) - ((Bitu) &wavtable);
  5947. + }
  5948. +
  5949. + //****************************************************
  5950. + //****************************************************
  5951. + //****************************************************
  5952. +
  5953. + // opl.cpp
  5954. +
  5955. + // - pure data
  5956. + WRITE_POD( &recipsamp, recipsamp );
  5957. + WRITE_POD( &wavtable, wavtable );
  5958. +
  5959. + WRITE_POD( &vibval_var1, vibval_var1 );
  5960. + WRITE_POD( &vibval_var2, vibval_var2 );
  5961. +
  5962. + //****************************************************
  5963. + //****************************************************
  5964. + //****************************************************
  5965. +
  5966. + // opl.h
  5967. +
  5968. + // - pure data
  5969. + WRITE_POD( &chip_num, chip_num );
  5970. +
  5971. + // - near-pure data
  5972. + WRITE_POD( &op, op );
  5973. +
  5974. + // - pure data
  5975. + WRITE_POD( &int_samplerate, int_samplerate );
  5976. + WRITE_POD( &status, status );
  5977. + WRITE_POD( &opl_index, opl_index );
  5978. + WRITE_POD( &adlibreg, adlibreg );
  5979. + WRITE_POD( &wave_sel, wave_sel );
  5980. +
  5981. + WRITE_POD( &vibtab_pos, vibtab_pos );
  5982. + WRITE_POD( &vibtab_add, vibtab_add );
  5983. + WRITE_POD( &tremtab_pos, tremtab_pos );
  5984. + WRITE_POD( &tremtab_add, tremtab_add );
  5985. + WRITE_POD( &generator_add, generator_add );
  5986. +
  5987. +
  5988. +
  5989. +
  5990. + // - reloc ptr (!!!)
  5991. + WRITE_POD( &cur_wform_idx, cur_wform_idx );
  5992. +}
  5993. +
  5994. +
  5995. +void adlib_loadstate( std::istream& stream )
  5996. +{
  5997. + Bit32u cur_wform_idx[MAXOPERATORS];
  5998. +
  5999. + //****************************************************
  6000. + //****************************************************
  6001. + //****************************************************
  6002. +
  6003. + // opl.cpp
  6004. +
  6005. + // - pure data
  6006. + READ_POD( &recipsamp, recipsamp );
  6007. + READ_POD( &wavtable, wavtable );
  6008. +
  6009. + READ_POD( &vibval_var1, vibval_var1 );
  6010. + READ_POD( &vibval_var2, vibval_var2 );
  6011. +
  6012. + //****************************************************
  6013. + //****************************************************
  6014. + //****************************************************
  6015. +
  6016. + // opl.h
  6017. +
  6018. + // - pure data
  6019. + READ_POD( &chip_num, chip_num );
  6020. +
  6021. + // - near-pure data
  6022. + READ_POD( &op, op );
  6023. +
  6024. + // - pure data
  6025. + READ_POD( &int_samplerate, int_samplerate );
  6026. + READ_POD( &status, status );
  6027. + READ_POD( &opl_index, opl_index );
  6028. + READ_POD( &adlibreg, adlibreg );
  6029. + READ_POD( &wave_sel, wave_sel );
  6030. +
  6031. + READ_POD( &vibtab_pos, vibtab_pos );
  6032. + READ_POD( &vibtab_add, vibtab_add );
  6033. + READ_POD( &tremtab_pos, tremtab_pos );
  6034. + READ_POD( &tremtab_add, tremtab_add );
  6035. + READ_POD( &generator_add, generator_add );
  6036. +
  6037. +
  6038. +
  6039. +
  6040. + // - reloc ptr (!!!)
  6041. + READ_POD( &cur_wform_idx, cur_wform_idx );
  6042. +
  6043. + //****************************************************
  6044. + //****************************************************
  6045. + //****************************************************
  6046. +
  6047. + for( int lcv=0; lcv<MAXOPERATORS; lcv++ ) {
  6048. + op[lcv].cur_wform = (Bit16s *) ((Bitu) &wavtable + cur_wform_idx[lcv]);
  6049. + }
  6050. +}
  6051. Index: src/hardware/pcspeaker.cpp
  6052. ===================================================================
  6053. --- src/hardware/pcspeaker.cpp (revision 4176)
  6054. +++ src/hardware/pcspeaker.cpp (working copy)
  6055. @@ -24,7 +24,9 @@
  6056. #include "setup.h"
  6057. #include "pic.h"
  6058.  
  6059. +#include "../save_state.h"
  6060.  
  6061. +
  6062. #ifndef PI
  6063. #define PI 3.14159265358979323846
  6064. #endif
  6065. @@ -358,3 +360,74 @@
  6066. test = new PCSPEAKER(sec);
  6067. sec->AddDestroyFunction(&PCSPEAKER_ShutDown,true);
  6068. }
  6069. +
  6070. +// save state support
  6071. +void POD_Save_PCSpeaker( std::ostream& stream )
  6072. +{
  6073. + const char pod_name[32] = "PCSpeaker";
  6074. +
  6075. + if( stream.fail() ) return;
  6076. + if( !test ) return;
  6077. + if( !spkr.chan ) return;
  6078. +
  6079. +
  6080. + WRITE_POD( &pod_name, pod_name );
  6081. +
  6082. + //*******************************************
  6083. + //*******************************************
  6084. + //*******************************************
  6085. +
  6086. + // - near-pure data
  6087. + WRITE_POD( &spkr, spkr );
  6088. +
  6089. + //*******************************************
  6090. + //*******************************************
  6091. + //*******************************************
  6092. +
  6093. + spkr.chan->SaveState(stream);
  6094. +}
  6095. +
  6096. +
  6097. +void POD_Load_PCSpeaker( std::istream& stream )
  6098. +{
  6099. + char pod_name[32] = {0};
  6100. +
  6101. + if( stream.fail() ) return;
  6102. + if( !test ) return;
  6103. + if( !spkr.chan ) return;
  6104. +
  6105. +
  6106. + // error checking
  6107. + READ_POD( &pod_name, pod_name );
  6108. + if( strcmp( pod_name, "PCSpeaker" ) ) {
  6109. + stream.clear( std::istream::failbit | std::istream::badbit );
  6110. + return;
  6111. + }
  6112. +
  6113. + //************************************************
  6114. + //************************************************
  6115. + //************************************************
  6116. +
  6117. + MixerChannel *chan_old;
  6118. +
  6119. +
  6120. + // - save static ptrs
  6121. + chan_old = spkr.chan;
  6122. +
  6123. + //*******************************************
  6124. + //*******************************************
  6125. + //*******************************************
  6126. +
  6127. + // - near-pure data
  6128. + READ_POD( &spkr, spkr );
  6129. +
  6130. + //*******************************************
  6131. + //*******************************************
  6132. + //*******************************************
  6133. +
  6134. + // - restore static ptrs
  6135. + spkr.chan = chan_old;
  6136. +
  6137. +
  6138. + spkr.chan->LoadState(stream);
  6139. +}
  6140. \ No newline at end of file
  6141. Index: src/hardware/pic.cpp
  6142. ===================================================================
  6143. --- src/hardware/pic.cpp (revision 4176)
  6144. +++ src/hardware/pic.cpp (working copy)
  6145. @@ -24,6 +24,8 @@
  6146. #include "timer.h"
  6147. #include "setup.h"
  6148.  
  6149. +#include "../save_state.h"
  6150. +
  6151. #define PIC_QUEUESIZE 512
  6152.  
  6153. struct PIC_Controller {
  6154. @@ -622,3 +624,366 @@
  6155. test = new PIC_8259A(sec);
  6156. sec->AddDestroyFunction(&PIC_Destroy);
  6157. }
  6158. +
  6159. +// PIC_EventHandlers
  6160. +extern void *cmos_timerevent_PIC_Event; // Cmos.cpp
  6161. +extern void *DISNEY_disable_PIC_Event; // Disney.cpp
  6162. +extern void *GUS_TimerEvent_PIC_Event; // Gus.cpp
  6163. +#if C_IPX
  6164. +extern void *IPX_AES_EventHandler_PIC_Event; // Ipx.cpp
  6165. +#endif
  6166. +extern void *KEYBOARD_TransferBuffer_PIC_Event; // Keyboard.cpp
  6167. +extern void *MOUSE_Limit_Events_PIC_Event; // Mouse.cpp
  6168. +extern void *MPU401_Event_PIC_Event; // Mpu401.cpp
  6169. +extern void *DMA_Silent_Event_PIC_Event; // Sblaster.cpp
  6170. +extern void *DSP_FinishReset_PIC_Event;
  6171. +extern void *DSP_RaiseIRQEvent_PIC_Event;
  6172. +extern void *END_DMA_Event_PIC_Event;
  6173. +extern void *Serial_EventHandler_PIC_Event; // Serialport.cpp
  6174. +extern void *PIT0_Event_PIC_Event; // Timer.cpp
  6175. +extern void *VGA_DisplayStartLatch_PIC_Event; // Vga.cpp
  6176. +extern void *VGA_DrawEGASingleLine_PIC_Event;
  6177. +extern void *VGA_DrawPart_PIC_Event;
  6178. +extern void *VGA_DrawSingleLine_PIC_Event;
  6179. +extern void *VGA_Other_VertInterrupt_PIC_Event;
  6180. +extern void *VGA_PanningLatch_PIC_Event;
  6181. +extern void *VGA_SetupDrawing_PIC_Event;
  6182. +extern void *VGA_VertInterrupt_PIC_Event;
  6183. +extern void *VGA_VerticalTimer_PIC_Event;
  6184. +
  6185. +#if C_NE2000
  6186. +extern void *NE2000_TX_Event_PIC_Event; // Ne2000.cpp
  6187. +#endif
  6188. +
  6189. +
  6190. +// PIC_TimerHandlers
  6191. +#if C_IPX
  6192. +extern void *IPX_ClientLoop_PIC_Timer; // Ipx.cpp
  6193. +extern void *IPX_ServerLoop_PIC_Timer; // Ipxserver.cpp
  6194. +#endif
  6195. +extern void *KEYBOARD_TickHandler_PIC_Timer; // Keyboard.cpp
  6196. +extern void *KEYBOARD_TickHandler_PIC_Timer; // Keyboard.cpp
  6197. +extern void *MIXER_Mix_NoSound_PIC_Timer; // Mixer.cpp
  6198. +extern void *MIXER_Mix_PIC_Timer;
  6199. +
  6200. +#if C_NE2000
  6201. +extern void *NE2000_Poller_PIC_Event; // Ne2000.cpp
  6202. +#endif
  6203. +
  6204. +
  6205. +const void *pic_state_event_table[] = {
  6206. + NULL,
  6207. + cmos_timerevent_PIC_Event,
  6208. + DISNEY_disable_PIC_Event,
  6209. + GUS_TimerEvent_PIC_Event,
  6210. +#if C_IPX
  6211. + IPX_AES_EventHandler_PIC_Event,
  6212. +#endif
  6213. + KEYBOARD_TransferBuffer_PIC_Event,
  6214. + MOUSE_Limit_Events_PIC_Event,
  6215. + MPU401_Event_PIC_Event,
  6216. + DMA_Silent_Event_PIC_Event,
  6217. + DSP_FinishReset_PIC_Event,
  6218. + DSP_RaiseIRQEvent_PIC_Event,
  6219. + END_DMA_Event_PIC_Event,
  6220. + END_DMA_Event_PIC_Event,
  6221. + Serial_EventHandler_PIC_Event,
  6222. + PIT0_Event_PIC_Event,
  6223. + VGA_DisplayStartLatch_PIC_Event,
  6224. + VGA_DrawEGASingleLine_PIC_Event,
  6225. + VGA_DrawPart_PIC_Event,
  6226. + VGA_DrawSingleLine_PIC_Event,
  6227. + VGA_Other_VertInterrupt_PIC_Event,
  6228. + VGA_PanningLatch_PIC_Event,
  6229. + VGA_SetupDrawing_PIC_Event,
  6230. + VGA_VertInterrupt_PIC_Event,
  6231. + VGA_VerticalTimer_PIC_Event,
  6232. +
  6233. +#if C_NE2000
  6234. + NE2000_TX_Event_PIC_Event,
  6235. +#endif
  6236. +};
  6237. +
  6238. +
  6239. +const void *pic_state_timer_table[] = {
  6240. + NULL,
  6241. +#if C_IPX
  6242. + IPX_ClientLoop_PIC_Timer,
  6243. + IPX_ServerLoop_PIC_Timer,
  6244. +#endif
  6245. + KEYBOARD_TickHandler_PIC_Timer,
  6246. + KEYBOARD_TickHandler_PIC_Timer,
  6247. + MIXER_Mix_NoSound_PIC_Timer,
  6248. + MIXER_Mix_PIC_Timer,
  6249. +
  6250. +#if C_NE2000
  6251. + NE2000_Poller_PIC_Event,
  6252. +#endif
  6253. +};
  6254. +
  6255. +
  6256. +
  6257. +//#include <windows.h>
  6258. +Bit16u PIC_State_FindEvent( Bitu addr ) {
  6259. + int size;
  6260. +
  6261. + size = sizeof(pic_state_event_table) / sizeof(void *);
  6262. + for( int lcv=0; lcv<size; lcv++ ) {
  6263. + if( addr == (Bitu) (pic_state_event_table[lcv]) ) return lcv;
  6264. + }
  6265. +
  6266. +
  6267. + // ERROR!! (place debug breakpoint here)
  6268. + //MessageBox(0,"PIC - State FindEvent",0,0);
  6269. + return 0xffff;
  6270. +}
  6271. +
  6272. +
  6273. +Bit16u PIC_State_FindTimer( Bitu addr ) {
  6274. + int size;
  6275. +
  6276. + size = sizeof(pic_state_timer_table) / sizeof(void *);
  6277. + for( int lcv=0; lcv<size; lcv++ ) {
  6278. + if( addr == (Bitu) (pic_state_timer_table[lcv]) ) return lcv;
  6279. + }
  6280. +
  6281. +
  6282. + // ERROR!! (place debug breakpoint here)
  6283. + //MessageBox(0,"PIC - State FindTimer",0,0);
  6284. + return 0xffff;
  6285. +}
  6286. +
  6287. +
  6288. +Bitu PIC_State_IndexEvent( Bit16u index ) {
  6289. + if( index == 0xffff ) return 0;
  6290. +
  6291. + return (Bitu) (pic_state_event_table[index]);
  6292. +}
  6293. +
  6294. +
  6295. +Bitu PIC_State_IndexTimer( Bit16u index ) {
  6296. + if( index == 0xffff ) return 0;
  6297. +
  6298. + return (Bitu) (pic_state_timer_table[index]);
  6299. +}
  6300. +
  6301. +
  6302. +//save state support
  6303. +namespace
  6304. +{
  6305. +class SerializePic : public SerializeGlobalPOD
  6306. +{
  6307. +public:
  6308. + SerializePic() : SerializeGlobalPOD("Pic")
  6309. + {}
  6310. +
  6311. +private:
  6312. + virtual void getBytes(std::ostream& stream)
  6313. + {
  6314. + Bit16u pic_free_idx, pic_next_idx;
  6315. + Bit16u pic_next_ptr[PIC_QUEUESIZE];
  6316. +
  6317. + TickerBlock *ticker_ptr;
  6318. + Bit16u ticker_size;
  6319. + Bit16u ticker_handler_idx;
  6320. +
  6321. +
  6322. + for( int lcv=0; lcv<PIC_QUEUESIZE; lcv++ ) {
  6323. + Bitu pic_addr;
  6324. +
  6325. + pic_addr = (Bitu) pic_queue.entries[lcv].next;
  6326. + pic_next_ptr[lcv] = 0xffff;
  6327. +
  6328. + for( int lcv2=0; lcv2<PIC_QUEUESIZE; lcv2++ ) {
  6329. + if( pic_addr == (Bitu) &pic_queue.entries[lcv2] ) {
  6330. + pic_next_ptr[lcv] = lcv2;
  6331. + break;
  6332. + }
  6333. + }
  6334. + }
  6335. +
  6336. +
  6337. + ticker_size = 0;
  6338. + ticker_ptr = firstticker;
  6339. + while( ticker_ptr != NULL ) {
  6340. + ticker_ptr = ticker_ptr->next;
  6341. + ticker_size++;
  6342. + }
  6343. +
  6344. + // ***************************************************
  6345. + // ***************************************************
  6346. + // ***************************************************
  6347. +
  6348. + SerializeGlobalPOD::getBytes(stream);
  6349. +
  6350. +
  6351. + // - data
  6352. + stream.write(reinterpret_cast<const char*>(&PIC_Ticks), sizeof(PIC_Ticks) );
  6353. + stream.write(reinterpret_cast<const char*>(&PIC_IRQCheck), sizeof(PIC_IRQCheck) );
  6354. +
  6355. + // - data structs
  6356. + stream.write(reinterpret_cast<const char*>(&pics), sizeof(pics) );
  6357. +
  6358. +
  6359. + pic_free_idx = 0xffff;
  6360. + pic_next_idx = 0xffff;
  6361. + for( int lcv=0; lcv<PIC_QUEUESIZE; lcv++ ) {
  6362. + Bit16u event_idx;
  6363. +
  6364. + // - data
  6365. + stream.write(reinterpret_cast<const char*>(&pic_queue.entries[lcv].index), sizeof(pic_queue.entries[lcv].index) );
  6366. + stream.write(reinterpret_cast<const char*>(&pic_queue.entries[lcv].value), sizeof(pic_queue.entries[lcv].value) );
  6367. +
  6368. + // - function ptr
  6369. + event_idx = PIC_State_FindEvent( (Bitu) (pic_queue.entries[lcv].pic_event) );
  6370. + stream.write(reinterpret_cast<const char*>(&event_idx), sizeof(event_idx) );
  6371. +
  6372. + // - reloc ptr
  6373. + stream.write(reinterpret_cast<const char*>(&pic_next_ptr[lcv]), sizeof(pic_next_ptr[lcv]) );
  6374. +
  6375. +
  6376. + if( &pic_queue.entries[lcv] == pic_queue.free_entry ) pic_free_idx = lcv;
  6377. + if( &pic_queue.entries[lcv] == pic_queue.next_entry ) pic_next_idx = lcv;
  6378. + }
  6379. +
  6380. + // - reloc ptrs
  6381. + stream.write(reinterpret_cast<const char*>(&pic_free_idx), sizeof(pic_free_idx) );
  6382. + stream.write(reinterpret_cast<const char*>(&pic_next_idx), sizeof(pic_next_idx) );
  6383. +
  6384. +
  6385. + // - data
  6386. + stream.write(reinterpret_cast<const char*>(&InEventService), sizeof(InEventService) );
  6387. + stream.write(reinterpret_cast<const char*>(&srv_lag), sizeof(srv_lag) );
  6388. +
  6389. +
  6390. + // - reloc ptr
  6391. + stream.write(reinterpret_cast<const char*>(&ticker_size), sizeof(ticker_size) );
  6392. +
  6393. + ticker_ptr = firstticker;
  6394. + for( int lcv=0; lcv<ticker_size; lcv++ ) {
  6395. + // - function ptr
  6396. + ticker_handler_idx = PIC_State_FindTimer( (Bitu) (ticker_ptr->handler) );
  6397. + stream.write(reinterpret_cast<const char*>(&ticker_handler_idx), sizeof(ticker_handler_idx) );
  6398. +
  6399. + // - reloc new ptr (leave alone)
  6400. + //stream.write(reinterpret_cast<const char*>(&ticker_ptr->next), sizeof(ticker_ptr->next) );
  6401. +
  6402. + ticker_ptr = ticker_ptr->next;
  6403. + }
  6404. +
  6405. +
  6406. + // - system (leave alone)
  6407. + //stream.write(reinterpret_cast<const char*>(&PIC_benchstart), sizeof(PIC_benchstart) );
  6408. + //stream.write(reinterpret_cast<const char*>(&PIC_tickstart), sizeof(PIC_tickstart) );
  6409. +
  6410. + // - static (leave alone)
  6411. + //test->saveState(stream);
  6412. + }
  6413. +
  6414. + virtual void setBytes(std::istream& stream)
  6415. + {
  6416. + Bit16u free_idx, next_idx;
  6417. + Bit16u ticker_size;
  6418. +
  6419. +
  6420. + SerializeGlobalPOD::setBytes(stream);
  6421. +
  6422. +
  6423. + // - data
  6424. + stream.read(reinterpret_cast<char*>(&PIC_Ticks), sizeof(PIC_Ticks) );
  6425. + stream.read(reinterpret_cast<char*>(&PIC_IRQCheck), sizeof(PIC_IRQCheck) );
  6426. +
  6427. + // - data structs
  6428. + stream.read(reinterpret_cast<char*>(&pics), sizeof(pics) );
  6429. +
  6430. +
  6431. + for( int lcv=0; lcv<PIC_QUEUESIZE; lcv++ ) {
  6432. + Bit16u event_idx, next_idx;
  6433. +
  6434. + // - data
  6435. + stream.read(reinterpret_cast<char*>(&pic_queue.entries[lcv].index), sizeof(pic_queue.entries[lcv].index) );
  6436. + stream.read(reinterpret_cast<char*>(&pic_queue.entries[lcv].value), sizeof(pic_queue.entries[lcv].value) );
  6437. +
  6438. +
  6439. + // - function ptr
  6440. + stream.read(reinterpret_cast<char*>(&event_idx), sizeof(event_idx) );
  6441. + pic_queue.entries[lcv].pic_event = (PIC_EventHandler) PIC_State_IndexEvent( event_idx );
  6442. +
  6443. +
  6444. + // - reloc ptr
  6445. + stream.read(reinterpret_cast<char*>(&next_idx), sizeof(next_idx) );
  6446. +
  6447. + pic_queue.entries[lcv].next = NULL;
  6448. + if( next_idx != 0xffff )
  6449. + pic_queue.entries[lcv].next = &pic_queue.entries[next_idx];
  6450. + }
  6451. +
  6452. + // - reloc ptrs
  6453. + stream.read(reinterpret_cast<char*>(&free_idx), sizeof(free_idx) );
  6454. + stream.read(reinterpret_cast<char*>(&next_idx), sizeof(next_idx) );
  6455. +
  6456. + pic_queue.free_entry = NULL;
  6457. + if( free_idx != 0xffff )
  6458. + pic_queue.free_entry = &pic_queue.entries[free_idx];
  6459. +
  6460. + pic_queue.next_entry = NULL;
  6461. + if( next_idx != 0xffff )
  6462. + pic_queue.next_entry = &pic_queue.entries[next_idx];
  6463. +
  6464. +
  6465. + // - data
  6466. + stream.read(reinterpret_cast<char*>(&InEventService), sizeof(InEventService) );
  6467. + stream.read(reinterpret_cast<char*>(&srv_lag), sizeof(srv_lag) );
  6468. +
  6469. +
  6470. + // 1- wipe old data
  6471. + // 2- insert new data
  6472. + while( firstticker != NULL ) {
  6473. + TickerBlock *ticker_ptr;
  6474. +
  6475. + ticker_ptr = firstticker;
  6476. + firstticker = firstticker->next;
  6477. +
  6478. + delete ticker_ptr;
  6479. + }
  6480. +
  6481. +
  6482. + // - reloc ptr
  6483. + stream.read(reinterpret_cast<char*>(&ticker_size), sizeof(ticker_size) );
  6484. +
  6485. + firstticker = NULL;
  6486. + if( ticker_size ) {
  6487. + TickerBlock *ticker_ptr;
  6488. +
  6489. + for( int lcv = 0; lcv<ticker_size; lcv++ ) {
  6490. + Bit16u ticker_idx;
  6491. +
  6492. + if( lcv == 0 ) {
  6493. + ticker_ptr = new TickerBlock;
  6494. + firstticker = ticker_ptr;
  6495. + }
  6496. + else {
  6497. + ticker_ptr->next = new TickerBlock;
  6498. + ticker_ptr = ticker_ptr->next;
  6499. + }
  6500. +
  6501. +
  6502. + // - function ptr
  6503. + stream.read(reinterpret_cast<char*>(&ticker_idx), sizeof(ticker_idx) );
  6504. + ticker_ptr->handler = (TIMER_TickHandler) PIC_State_IndexTimer( ticker_idx );
  6505. +
  6506. + // - reloc new ptr (linked list)
  6507. + ticker_ptr->next = NULL;
  6508. + }
  6509. + }
  6510. +
  6511. +
  6512. + // - system (leave alone)
  6513. + //stream.read(reinterpret_cast<char*>(&PIC_benchstart), sizeof(PIC_benchstart) );
  6514. + //stream.read(reinterpret_cast<char*>(&PIC_tickstart), sizeof(PIC_tickstart) );
  6515. +
  6516. + // - static (leave alone)
  6517. + //test->loadState(stream);
  6518. + }
  6519. +} dummy;
  6520. +}
  6521. Index: src/hardware/sblaster.cpp
  6522. ===================================================================
  6523. --- src/hardware/sblaster.cpp (revision 4176)
  6524. +++ src/hardware/sblaster.cpp (working copy)
  6525. @@ -29,6 +29,9 @@
  6526. #include "hardware.h"
  6527. #include "setup.h"
  6528. #include "support.h"
  6529. +
  6530. +#include "../save_state.h"
  6531. +
  6532. #include "shell.h"
  6533. using namespace std;
  6534.  
  6535. @@ -1736,3 +1739,125 @@
  6536. test = new SBLASTER(sec);
  6537. sec->AddDestroyFunction(&SBLASTER_ShutDown,true);
  6538. }
  6539. +
  6540. +// save state support
  6541. +void *DMA_Silent_Event_PIC_Event = (void*)DMA_Silent_Event;
  6542. +void *DSP_FinishReset_PIC_Event = (void*)DSP_FinishReset;
  6543. +void *DSP_RaiseIRQEvent_PIC_Event = (void*)DSP_RaiseIRQEvent;
  6544. +void *END_DMA_Event_PIC_Event = (void*)END_DMA_Event;
  6545. +
  6546. +void *SB_DSP_DMA_CallBack_Func = (void*)DSP_DMA_CallBack;
  6547. +void *SB_DSP_ADC_CallBack_Func = (void*)DSP_ADC_CallBack;
  6548. +void *SB_DSP_E2_DMA_CallBack_Func = (void*)DSP_E2_DMA_CallBack;
  6549. +
  6550. +
  6551. +void POD_Save_Sblaster( std::ostream& stream )
  6552. +{
  6553. + const char pod_name[32] = "SBlaster";
  6554. +
  6555. + if( stream.fail() ) return;
  6556. + if( !test ) return;
  6557. + if( !sb.chan ) return;
  6558. +
  6559. +
  6560. + WRITE_POD( &pod_name, pod_name );
  6561. +
  6562. +
  6563. + //*******************************************
  6564. + //*******************************************
  6565. + //*******************************************
  6566. +
  6567. + Bit8u dma_idx;
  6568. +
  6569. +
  6570. + dma_idx = 0xff;
  6571. + for( int lcv=0; lcv<8; lcv++ ) {
  6572. + if( sb.dma.chan == GetDMAChannel(lcv) ) { dma_idx = lcv; break; }
  6573. + }
  6574. +
  6575. + // *******************************************
  6576. + // *******************************************
  6577. + // *******************************************
  6578. +
  6579. + // - near-pure data
  6580. + WRITE_POD( &sb, sb );
  6581. +
  6582. + // - pure data
  6583. + WRITE_POD( &ASP_regs, ASP_regs );
  6584. + WRITE_POD( &ASP_init_in_progress, ASP_init_in_progress );
  6585. + WRITE_POD( &last_dma_callback, last_dma_callback );
  6586. +
  6587. +
  6588. +
  6589. + // - reloc ptr
  6590. + WRITE_POD( &dma_idx, dma_idx );
  6591. +
  6592. + // *******************************************
  6593. + // *******************************************
  6594. + // *******************************************
  6595. +
  6596. + sb.chan->SaveState(stream);
  6597. +}
  6598. +
  6599. +
  6600. +void POD_Load_Sblaster( std::istream& stream )
  6601. +{
  6602. + char pod_name[32] = {0};
  6603. +
  6604. + if( stream.fail() ) return;
  6605. + if( !test ) return;
  6606. + if( !sb.chan ) return;
  6607. +
  6608. +
  6609. + // error checking
  6610. + READ_POD( &pod_name, pod_name );
  6611. + if( strcmp( pod_name, "SBlaster" ) ) {
  6612. + stream.clear( std::istream::failbit | std::istream::badbit );
  6613. + return;
  6614. + }
  6615. +
  6616. + //************************************************
  6617. + //************************************************
  6618. + //************************************************
  6619. +
  6620. + Bit8u dma_idx;
  6621. + MixerChannel *mixer_old;
  6622. +
  6623. +
  6624. + // save static ptr
  6625. + mixer_old = sb.chan;
  6626. +
  6627. + //*******************************************
  6628. + //*******************************************
  6629. + //*******************************************
  6630. +
  6631. + // - near-pure data
  6632. + READ_POD( &sb, sb );
  6633. +
  6634. + // - pure data
  6635. + READ_POD( &ASP_regs, ASP_regs );
  6636. + READ_POD( &ASP_init_in_progress, ASP_init_in_progress );
  6637. + READ_POD( &last_dma_callback, last_dma_callback );
  6638. +
  6639. +
  6640. +
  6641. + // - reloc ptr
  6642. + READ_POD( &dma_idx, dma_idx );
  6643. +
  6644. + //*******************************************
  6645. + //*******************************************
  6646. + //*******************************************
  6647. +
  6648. + sb.dma.chan = NULL;
  6649. + if( dma_idx != 0xff ) sb.dma.chan = GetDMAChannel(dma_idx);
  6650. +
  6651. + //*******************************************
  6652. + //*******************************************
  6653. + //*******************************************
  6654. +
  6655. + // restore static ptr
  6656. + sb.chan = mixer_old;
  6657. +
  6658. +
  6659. + sb.chan->LoadState(stream);
  6660. +}
  6661. \ No newline at end of file
  6662. Index: src/hardware/serialport/serialport.cpp
  6663. ===================================================================
  6664. --- src/hardware/serialport/serialport.cpp (revision 4176)
  6665. +++ src/hardware/serialport/serialport.cpp (working copy)
  6666. @@ -1296,3 +1296,6 @@
  6667. testSerialPortsBaseclass = new SERIALPORTS (sec);
  6668. sec->AddDestroyFunction (&SERIAL_Destroy, true);
  6669. }
  6670. +
  6671. +// save state support
  6672. +void *Serial_EventHandler_PIC_Event = (void*)Serial_EventHandler;
  6673. \ No newline at end of file
  6674. Index: src/hardware/tandy_sound.cpp
  6675. ===================================================================
  6676. --- src/hardware/tandy_sound.cpp (revision 4176)
  6677. +++ src/hardware/tandy_sound.cpp (working copy)
  6678. @@ -33,6 +33,7 @@
  6679. #include "mame/emu.h"
  6680. #include "mame/sn76496.h"
  6681.  
  6682. +#include "../save_state.h"
  6683.  
  6684. #define SOUND_CLOCK (14318180 / 4)
  6685.  
  6686. @@ -355,3 +356,109 @@
  6687. test = new TANDYSOUND(sec);
  6688. sec->AddDestroyFunction(&TANDYSOUND_ShutDown,true);
  6689. }
  6690. +
  6691. +// save state support
  6692. +void *TandyDAC_DMA_CallBack_Func = (void*)TandyDAC_DMA_CallBack;
  6693. +
  6694. +
  6695. +void POD_Save_Tandy_Sound( std::ostream& stream )
  6696. +{
  6697. + const char pod_name[32] = "Tandy";
  6698. +
  6699. + if( stream.fail() ) return;
  6700. + if( !test ) return;
  6701. + if( !tandy.chan ) return;
  6702. +
  6703. +
  6704. + WRITE_POD( &pod_name, pod_name );
  6705. +
  6706. + //*******************************************
  6707. + //*******************************************
  6708. + //*******************************************
  6709. +
  6710. + Bit8u dma_idx;
  6711. +
  6712. +
  6713. + dma_idx = 0xff;
  6714. + for( int lcv=0; lcv<8; lcv++ ) {
  6715. + if( tandy.dac.dma.chan == GetDMAChannel(lcv) ) { dma_idx = lcv; break; }
  6716. + }
  6717. +
  6718. + // *******************************************
  6719. + // *******************************************
  6720. + // *******************************************
  6721. +
  6722. + // - near-pure data
  6723. + WRITE_POD( &tandy, tandy );
  6724. +
  6725. + // - reloc ptr
  6726. + WRITE_POD( &dma_idx, dma_idx );
  6727. +
  6728. + // *******************************************
  6729. + // *******************************************
  6730. + // *******************************************
  6731. +
  6732. + activeDevice->SaveState(stream);
  6733. +
  6734. + tandy.chan->SaveState(stream);
  6735. + tandy.dac.chan->SaveState(stream);
  6736. +}
  6737. +
  6738. +
  6739. +void POD_Load_Tandy_Sound( std::istream& stream )
  6740. +{
  6741. + char pod_name[32] = {0};
  6742. +
  6743. + if( stream.fail() ) return;
  6744. + if( !test ) return;
  6745. + if( !tandy.chan ) return;
  6746. +
  6747. +
  6748. + // error checking
  6749. + READ_POD( &pod_name, pod_name );
  6750. + if( strcmp( pod_name, "Tandy" ) ) {
  6751. + stream.clear( std::istream::failbit | std::istream::badbit );
  6752. + return;
  6753. + }
  6754. +
  6755. + //************************************************
  6756. + //************************************************
  6757. + //************************************************
  6758. +
  6759. + Bit8u dma_idx;
  6760. + MixerChannel *chan_old, *dac_chan_old;
  6761. +
  6762. + // - save static ptrs
  6763. + chan_old = tandy.chan;
  6764. + dac_chan_old = tandy.dac.chan;
  6765. +
  6766. + // *******************************************
  6767. + // *******************************************
  6768. + // *******************************************
  6769. +
  6770. + // - near-pure data
  6771. + READ_POD( &tandy, tandy );
  6772. +
  6773. + // - reloc ptr
  6774. + READ_POD( &dma_idx, dma_idx );
  6775. +
  6776. + // *******************************************
  6777. + // *******************************************
  6778. + // *******************************************
  6779. +
  6780. + tandy.dac.dma.chan = NULL;
  6781. + if( dma_idx != 0xff ) tandy.dac.dma.chan = GetDMAChannel(dma_idx);
  6782. +
  6783. + // *******************************************
  6784. + // *******************************************
  6785. + // *******************************************
  6786. +
  6787. + // - restore static ptrs
  6788. + tandy.chan = chan_old;
  6789. + tandy.dac.chan = dac_chan_old;
  6790. +
  6791. + activeDevice->LoadState(stream);
  6792. +
  6793. + tandy.chan->LoadState(stream);
  6794. + tandy.dac.chan->LoadState(stream);
  6795. +}
  6796. \ No newline at end of file
  6797. Index: src/hardware/timer.cpp
  6798. ===================================================================
  6799. --- src/hardware/timer.cpp (revision 4176)
  6800. +++ src/hardware/timer.cpp (working copy)
  6801. @@ -26,6 +26,8 @@
  6802. #include "timer.h"
  6803. #include "setup.h"
  6804.  
  6805. +#include "../save_state.h"
  6806. +
  6807. static INLINE void BIN2BCD(Bit16u& val) {
  6808. Bit16u temp=val%10 + (((val/10)%10)<<4)+ (((val/100)%10)<<8) + (((val/1000)%10)<<12);
  6809. val=temp;
  6810. @@ -467,3 +469,22 @@
  6811. test = new TIMER(sec);
  6812. sec->AddDestroyFunction(&TIMER_Destroy);
  6813. }
  6814. +
  6815. +//save state support
  6816. +void *PIT0_Event_PIC_Event = (void*)PIT0_Event;
  6817. +
  6818. +
  6819. +namespace
  6820. +{
  6821. +class SerializeTimer : public SerializeGlobalPOD
  6822. +{
  6823. +public:
  6824. + SerializeTimer() : SerializeGlobalPOD("IntTimer10")
  6825. + {
  6826. + registerPOD(pit);
  6827. + registerPOD(gate2);
  6828. + registerPOD(latched_timerstatus);
  6829. + registerPOD(latched_timerstatus_locked);
  6830. + }
  6831. +} dummy;
  6832. +}
  6833. \ No newline at end of file
  6834. Index: src/hardware/vga.cpp
  6835. ===================================================================
  6836. --- src/hardware/vga.cpp (revision 4176)
  6837. +++ src/hardware/vga.cpp (working copy)
  6838. @@ -23,6 +23,9 @@
  6839. #include "pic.h"
  6840. #include "vga.h"
  6841.  
  6842. +#include "../save_state.h"
  6843. +#include "mem.h"
  6844. +
  6845. #include <string.h>
  6846.  
  6847. VGA_Type vga;
  6848. @@ -261,3 +264,279 @@
  6849. break;
  6850. }
  6851. }
  6852. +
  6853. +extern void POD_Save_VGA_Draw( std::ostream & );
  6854. +extern void POD_Save_VGA_Seq( std::ostream & );
  6855. +extern void POD_Save_VGA_Attr( std::ostream & );
  6856. +extern void POD_Save_VGA_Crtc( std::ostream & );
  6857. +extern void POD_Save_VGA_Gfx( std::ostream & );
  6858. +extern void POD_Save_VGA_Dac( std::ostream & );
  6859. +extern void POD_Save_VGA_S3( std::ostream & );
  6860. +extern void POD_Save_VGA_Other( std::ostream & );
  6861. +extern void POD_Save_VGA_Memory( std::ostream & );
  6862. +extern void POD_Save_VGA_Paradise( std::ostream & );
  6863. +extern void POD_Save_VGA_Tseng( std::ostream & );
  6864. +extern void POD_Save_VGA_XGA( std::ostream & );
  6865. +extern void POD_Load_VGA_Draw( std::istream & );
  6866. +extern void POD_Load_VGA_Seq( std::istream & );
  6867. +extern void POD_Load_VGA_Attr( std::istream & );
  6868. +extern void POD_Load_VGA_Crtc( std::istream & );
  6869. +extern void POD_Load_VGA_Gfx( std::istream & );
  6870. +extern void POD_Load_VGA_Dac( std::istream & );
  6871. +extern void POD_Load_VGA_S3( std::istream & );
  6872. +extern void POD_Load_VGA_Other( std::istream & );
  6873. +extern void POD_Load_VGA_Memory( std::istream & );
  6874. +extern void POD_Load_VGA_Paradise( std::istream & );
  6875. +extern void POD_Load_VGA_Tseng( std::istream & );
  6876. +extern void POD_Load_VGA_XGA( std::istream & );
  6877. +
  6878. +//save state support
  6879. +void *VGA_SetupDrawing_PIC_Event = (void*)VGA_SetupDrawing;
  6880. +
  6881. +
  6882. +namespace {
  6883. +class SerializeVga : public SerializeGlobalPOD {
  6884. +public:
  6885. + SerializeVga() : SerializeGlobalPOD("Vga")
  6886. + {}
  6887. +
  6888. +private:
  6889. + virtual void getBytes(std::ostream& stream)
  6890. + {
  6891. + Bit32u tandy_drawbase_idx, tandy_membase_idx;
  6892. +
  6893. +
  6894. +
  6895. +
  6896. + if( vga.tandy.draw_base == vga.mem.linear ) tandy_drawbase_idx=0xffffffff;
  6897. + else tandy_drawbase_idx = vga.tandy.draw_base - MemBase;
  6898. +
  6899. + if( vga.tandy.mem_base == vga.mem.linear ) tandy_membase_idx=0xffffffff;
  6900. + else tandy_membase_idx = vga.tandy.mem_base - MemBase;
  6901. +
  6902. + //********************************
  6903. + //********************************
  6904. +
  6905. + SerializeGlobalPOD::getBytes(stream);
  6906. +
  6907. +
  6908. + // - pure data
  6909. + WRITE_POD( &vga.mode, vga.mode );
  6910. + WRITE_POD( &vga.misc_output, vga.misc_output );
  6911. +
  6912. +
  6913. + // VGA_Draw.cpp
  6914. + POD_Save_VGA_Draw(stream);
  6915. +
  6916. +
  6917. + // - pure struct data
  6918. + WRITE_POD( &vga.config, vga.config );
  6919. + WRITE_POD( &vga.internal, vga.internal );
  6920. +
  6921. +
  6922. + // VGA_Seq.cpp / VGA_Attr.cpp / (..)
  6923. + POD_Save_VGA_Seq(stream);
  6924. + POD_Save_VGA_Attr(stream);
  6925. + POD_Save_VGA_Crtc(stream);
  6926. + POD_Save_VGA_Gfx(stream);
  6927. + POD_Save_VGA_Dac(stream);
  6928. +
  6929. +
  6930. + // - pure data
  6931. + WRITE_POD( &vga.latch, vga.latch );
  6932. +
  6933. +
  6934. + // VGA_S3.cpp
  6935. + POD_Save_VGA_S3(stream);
  6936. +
  6937. +
  6938. + // - pure struct data
  6939. + WRITE_POD( &vga.svga, vga.svga );
  6940. + WRITE_POD( &vga.herc, vga.herc );
  6941. +
  6942. +
  6943. + // - near-pure struct data
  6944. + WRITE_POD( &vga.tandy, vga.tandy );
  6945. +
  6946. + // - reloc data
  6947. + WRITE_POD( &tandy_drawbase_idx, tandy_drawbase_idx );
  6948. + WRITE_POD( &tandy_membase_idx, tandy_membase_idx );
  6949. +
  6950. +
  6951. + // vga_other.cpp / vga_memory.cpp
  6952. + POD_Save_VGA_Other(stream);
  6953. + POD_Save_VGA_Memory(stream);
  6954. +
  6955. +
  6956. + // - pure data
  6957. + WRITE_POD( &vga.vmemwrap, vga.vmemwrap );
  6958. +
  6959. +
  6960. + // - static ptrs + 'new' data
  6961. + //Bit8u* fastmem;
  6962. + //Bit8u* fastmem_orgptr;
  6963. +
  6964. + // - 'new' data
  6965. + WRITE_POD_SIZE( vga.fastmem_orgptr, sizeof(Bit8u) * ((vga.vmemsize << 1) + 4096 + 16) );
  6966. +
  6967. +
  6968. + // - pure data (variable on S3 card)
  6969. + WRITE_POD( &vga.vmemsize, vga.vmemsize );
  6970. +
  6971. +
  6972. +#ifdef VGA_KEEP_CHANGES
  6973. + // - static ptr
  6974. + //Bit8u* map;
  6975. +
  6976. + // - 'new' data
  6977. + WRITE_POD_SIZE( vga.changes.map, sizeof(Bit8u) * (VGA_MEMORY >> VGA_CHANGE_SHIFT) + 32 );
  6978. +
  6979. +
  6980. + // - pure data
  6981. + WRITE_POD( &vga.changes.checkMask, vga.changes.checkMask );
  6982. + WRITE_POD( &vga.changes.frame, vga.changes.frame );
  6983. + WRITE_POD( &vga.changes.writeMask, vga.changes.writeMask );
  6984. + WRITE_POD( &vga.changes.active, vga.changes.active );
  6985. + WRITE_POD( &vga.changes.clearMask, vga.changes.clearMask );
  6986. + WRITE_POD( &vga.changes.start, vga.changes.start );
  6987. + WRITE_POD( &vga.changes.last, vga.changes.last );
  6988. + WRITE_POD( &vga.changes.lastAddress, vga.changes.lastAddress );
  6989. +#endif
  6990. +
  6991. +
  6992. + // - pure data
  6993. + WRITE_POD( &vga.lfb.page, vga.lfb.page );
  6994. + WRITE_POD( &vga.lfb.addr, vga.lfb.addr );
  6995. + WRITE_POD( &vga.lfb.mask, vga.lfb.mask );
  6996. +
  6997. + // - static ptr
  6998. + //PageHandler *handler;
  6999. +
  7000. +
  7001. + // VGA_paradise.cpp / VGA_tseng.cpp / VGA_xga.cpp
  7002. + POD_Save_VGA_Paradise(stream);
  7003. + POD_Save_VGA_Tseng(stream);
  7004. + POD_Save_VGA_XGA(stream);
  7005. + }
  7006. +
  7007. + virtual void setBytes(std::istream& stream)
  7008. + {
  7009. + Bit32u tandy_drawbase_idx, tandy_membase_idx;
  7010. +
  7011. +
  7012. +
  7013. + //********************************
  7014. + //********************************
  7015. +
  7016. + SerializeGlobalPOD::setBytes(stream);
  7017. +
  7018. +
  7019. + // - pure data
  7020. + READ_POD( &vga.mode, vga.mode );
  7021. + READ_POD( &vga.misc_output, vga.misc_output );
  7022. +
  7023. +
  7024. + // VGA_Draw.cpp
  7025. + POD_Load_VGA_Draw(stream);
  7026. +
  7027. +
  7028. + // - pure struct data
  7029. + READ_POD( &vga.config, vga.config );
  7030. + READ_POD( &vga.internal, vga.internal );
  7031. +
  7032. +
  7033. + // VGA_Seq.cpp / VGA_Attr.cpp / (..)
  7034. + POD_Load_VGA_Seq(stream);
  7035. + POD_Load_VGA_Attr(stream);
  7036. + POD_Load_VGA_Crtc(stream);
  7037. + POD_Load_VGA_Gfx(stream);
  7038. + POD_Load_VGA_Dac(stream);
  7039. +
  7040. +
  7041. + // - pure data
  7042. + READ_POD( &vga.latch, vga.latch );
  7043. +
  7044. +
  7045. + // VGA_S3.cpp
  7046. + POD_Load_VGA_S3(stream);
  7047. +
  7048. +
  7049. + // - pure struct data
  7050. + READ_POD( &vga.svga, vga.svga );
  7051. + READ_POD( &vga.herc, vga.herc );
  7052. +
  7053. +
  7054. + // - near-pure struct data
  7055. + READ_POD( &vga.tandy, vga.tandy );
  7056. +
  7057. + // - reloc data
  7058. + READ_POD( &tandy_drawbase_idx, tandy_drawbase_idx );
  7059. + READ_POD( &tandy_membase_idx, tandy_membase_idx );
  7060. +
  7061. +
  7062. + // vga_other.cpp / vga_memory.cpp
  7063. + POD_Load_VGA_Other(stream);
  7064. + POD_Load_VGA_Memory(stream);
  7065. +
  7066. +
  7067. + // - pure data
  7068. + READ_POD( &vga.vmemwrap, vga.vmemwrap );
  7069. +
  7070. +
  7071. + // - static ptrs + 'new' data
  7072. + //Bit8u* fastmem;
  7073. + //Bit8u* fastmem_orgptr;
  7074. +
  7075. + // - 'new' data
  7076. + READ_POD_SIZE( vga.fastmem_orgptr, sizeof(Bit8u) * ((vga.vmemsize << 1) + 4096 + 16) );
  7077. +
  7078. +
  7079. + // - pure data (variable on S3 card)
  7080. + READ_POD( &vga.vmemsize, vga.vmemsize );
  7081. +
  7082. +
  7083. +#ifdef VGA_KEEP_CHANGES
  7084. + // - static ptr
  7085. + //Bit8u* map;
  7086. +
  7087. + // - 'new' data
  7088. + READ_POD_SIZE( vga.changes.map, sizeof(Bit8u) * (VGA_MEMORY >> VGA_CHANGE_SHIFT) + 32 );
  7089. +
  7090. +
  7091. + // - pure data
  7092. + READ_POD( &vga.changes.checkMask, vga.changes.checkMask );
  7093. + READ_POD( &vga.changes.frame, vga.changes.frame );
  7094. + READ_POD( &vga.changes.writeMask, vga.changes.writeMask );
  7095. + READ_POD( &vga.changes.active, vga.changes.active );
  7096. + READ_POD( &vga.changes.clearMask, vga.changes.clearMask );
  7097. + READ_POD( &vga.changes.start, vga.changes.start );
  7098. + READ_POD( &vga.changes.last, vga.changes.last );
  7099. + READ_POD( &vga.changes.lastAddress, vga.changes.lastAddress );
  7100. +#endif
  7101. +
  7102. +
  7103. + // - pure data
  7104. + READ_POD( &vga.lfb.page, vga.lfb.page );
  7105. + READ_POD( &vga.lfb.addr, vga.lfb.addr );
  7106. + READ_POD( &vga.lfb.mask, vga.lfb.mask );
  7107. +
  7108. + // - static ptr
  7109. + //PageHandler *handler;
  7110. +
  7111. +
  7112. + // VGA_paradise.cpp / VGA_tseng.cpp / VGA_xga.cpp
  7113. + POD_Load_VGA_Paradise(stream);
  7114. + POD_Load_VGA_Tseng(stream);
  7115. + POD_Load_VGA_XGA(stream);
  7116. +
  7117. + //********************************
  7118. + //********************************
  7119. +
  7120. + if( tandy_drawbase_idx == 0xffffffff ) vga.tandy.draw_base = vga.mem.linear;
  7121. + else vga.tandy.draw_base = MemBase + tandy_drawbase_idx;
  7122. +
  7123. + if( tandy_membase_idx == 0xffffffff ) vga.tandy.mem_base = vga.mem.linear;
  7124. + else vga.tandy.mem_base = MemBase + tandy_membase_idx;
  7125. + }
  7126. +} dummy;
  7127. +}
  7128. \ No newline at end of file
  7129. Index: src/hardware/vga_attr.cpp
  7130. ===================================================================
  7131. --- src/hardware/vga_attr.cpp (revision 4176)
  7132. +++ src/hardware/vga_attr.cpp (working copy)
  7133. @@ -21,6 +21,8 @@
  7134. #include "inout.h"
  7135. #include "vga.h"
  7136.  
  7137. +#include "../save_state.h"
  7138. +
  7139. #define attr(blah) vga.attr.blah
  7140.  
  7141. void VGA_ATTR_SetEGAMonitorPalette(EGAMonitorMode m) {
  7142. @@ -294,3 +296,23 @@
  7143. }
  7144. }
  7145. }
  7146. +
  7147. +// save state support
  7148. +void POD_Save_VGA_Attr( std::ostream& stream )
  7149. +{
  7150. + // - pure struct data
  7151. + WRITE_POD( &vga.attr, vga.attr );
  7152. +
  7153. +
  7154. + // no static globals found
  7155. +}
  7156. +
  7157. +
  7158. +void POD_Load_VGA_Attr( std::istream& stream )
  7159. +{
  7160. + // - pure struct data
  7161. + READ_POD( &vga.attr, vga.attr );
  7162. +
  7163. +
  7164. + // no static globals found
  7165. +}
  7166. \ No newline at end of file
  7167. Index: src/hardware/vga_crtc.cpp
  7168. ===================================================================
  7169. --- src/hardware/vga_crtc.cpp (revision 4176)
  7170. +++ src/hardware/vga_crtc.cpp (working copy)
  7171. @@ -26,6 +26,8 @@
  7172. #include "video.h"
  7173. #include "pic.h"
  7174.  
  7175. +#include "../save_state.h"
  7176. +
  7177. #define crtc(blah) vga.crtc.blah
  7178.  
  7179.  
  7180. @@ -430,6 +432,23 @@
  7181. }
  7182. }
  7183.  
  7184. +// save state support
  7185.  
  7186. +void POD_Save_VGA_Crtc( std::ostream& stream )
  7187. +{
  7188. + // - pure struct data
  7189. + WRITE_POD( &vga.crtc, vga.crtc );
  7190.  
  7191.  
  7192. + // no static globals found
  7193. +}
  7194. +
  7195. +
  7196. +void POD_Load_VGA_Crtc( std::istream& stream )
  7197. +{
  7198. + // - pure struct data
  7199. + READ_POD( &vga.crtc, vga.crtc );
  7200. +
  7201. +
  7202. + // no static globals found
  7203. +}
  7204. \ No newline at end of file
  7205. Index: src/hardware/vga_dac.cpp
  7206. ===================================================================
  7207. --- src/hardware/vga_dac.cpp (revision 4176)
  7208. +++ src/hardware/vga_dac.cpp (working copy)
  7209. @@ -21,6 +21,8 @@
  7210. #include "render.h"
  7211. #include "vga.h"
  7212.  
  7213. +#include "../save_state.h"
  7214. +
  7215. /*
  7216. 3C6h (R/W): PEL Mask
  7217. bit 0-7 This register is anded with the palette index sent for each dot.
  7218. @@ -216,3 +218,24 @@
  7219. IO_RegisterReadHandler(0x3c9,read_p3c9,IO_MB);
  7220. }
  7221. }
  7222. +
  7223. +// save state support
  7224. +
  7225. +void POD_Save_VGA_Dac( std::ostream& stream )
  7226. +{
  7227. + // - pure struct data
  7228. + WRITE_POD( &vga.dac, vga.dac );
  7229. +
  7230. +
  7231. + // no static globals found
  7232. +}
  7233. +
  7234. +
  7235. +void POD_Load_VGA_Dac( std::istream& stream )
  7236. +{
  7237. + // - pure struct data
  7238. + READ_POD( &vga.dac, vga.dac );
  7239. +
  7240. +
  7241. + // no static globals found
  7242. +}
  7243. \ No newline at end of file
  7244. Index: src/hardware/vga_draw.cpp
  7245. ===================================================================
  7246. --- src/hardware/vga_draw.cpp (revision 4176)
  7247. +++ src/hardware/vga_draw.cpp (working copy)
  7248. @@ -26,6 +26,8 @@
  7249. #include "vga.h"
  7250. #include "pic.h"
  7251.  
  7252. +#include "../save_state.h"
  7253. +
  7254. //#undef C_DEBUG
  7255. //#define C_DEBUG 1
  7256. //#define LOG(X,Y) LOG_MSG
  7257. @@ -1620,3 +1622,285 @@
  7258. }
  7259. }
  7260. }
  7261. +
  7262. +// save state support
  7263. +void *VGA_DisplayStartLatch_PIC_Event = (void*)VGA_DisplayStartLatch;
  7264. +void *VGA_DrawEGASingleLine_PIC_Event = (void*)VGA_DrawEGASingleLine;
  7265. +void *VGA_DrawPart_PIC_Event = (void*)VGA_DrawPart;
  7266. +void *VGA_DrawSingleLine_PIC_Event = (void*)VGA_DrawSingleLine;
  7267. +void *VGA_Other_VertInterrupt_PIC_Event = (void*)VGA_Other_VertInterrupt;
  7268. +void *VGA_PanningLatch_PIC_Event = (void*)VGA_PanningLatch;
  7269. +void *VGA_VertInterrupt_PIC_Event = (void*)VGA_VertInterrupt;
  7270. +void *VGA_VerticalTimer_PIC_Event = (void*)VGA_VerticalTimer;
  7271. +
  7272. +
  7273. +void POD_Save_VGA_Draw( std::ostream& stream )
  7274. +{
  7275. + Bit8u linear_base_idx;
  7276. + Bit8u font_tables_idx[2];
  7277. + Bit8u drawline_idx;
  7278. +
  7279. +
  7280. + if(0) {}
  7281. + else if( vga.draw.linear_base == vga.mem.linear ) linear_base_idx = 0;
  7282. + else if( vga.draw.linear_base == vga.fastmem ) linear_base_idx = 1;
  7283. +
  7284. +
  7285. + for( int lcv=0; lcv<2; lcv++ ) {
  7286. + if(0) {}
  7287. + else if( vga.draw.font_tables[lcv] == &(vga.draw.font[0*1024]) ) font_tables_idx[lcv] = 0;
  7288. + else if( vga.draw.font_tables[lcv] == &(vga.draw.font[8*1024]) ) font_tables_idx[lcv] = 1;
  7289. + else if( vga.draw.font_tables[lcv] == &(vga.draw.font[16*1024]) ) font_tables_idx[lcv] = 2;
  7290. + else if( vga.draw.font_tables[lcv] == &(vga.draw.font[24*1024]) ) font_tables_idx[lcv] = 3;
  7291. + else if( vga.draw.font_tables[lcv] == &(vga.draw.font[32*1024]) ) font_tables_idx[lcv] = 4;
  7292. + else if( vga.draw.font_tables[lcv] == &(vga.draw.font[40*1024]) ) font_tables_idx[lcv] = 5;
  7293. + else if( vga.draw.font_tables[lcv] == &(vga.draw.font[48*1024]) ) font_tables_idx[lcv] = 6;
  7294. + else if( vga.draw.font_tables[lcv] == &(vga.draw.font[56*1024]) ) font_tables_idx[lcv] = 7;
  7295. + }
  7296. +
  7297. +
  7298. + if(0) {}
  7299. + else if( VGA_DrawLine == VGA_Draw_1BPP_Line ) drawline_idx = 1;
  7300. + else if( VGA_DrawLine == VGA_Draw_2BPP_Line ) drawline_idx = 3;
  7301. + else if( VGA_DrawLine == VGA_Draw_2BPPHiRes_Line ) drawline_idx = 4;
  7302. + else if( VGA_DrawLine == VGA_Draw_CGA16_Line ) drawline_idx = 5;
  7303. + else if( VGA_DrawLine == VGA_Draw_4BPP_Line ) drawline_idx = 6;
  7304. + else if( VGA_DrawLine == VGA_Draw_4BPP_Line_Double ) drawline_idx = 7;
  7305. + else if( VGA_DrawLine == VGA_Draw_Linear_Line ) drawline_idx = 8;
  7306. + else if( VGA_DrawLine == VGA_Draw_Xlat16_Linear_Line ) drawline_idx = 9;
  7307. + else if( VGA_DrawLine == VGA_Draw_VGA_Line_HWMouse ) drawline_idx = 11;
  7308. + else if( VGA_DrawLine == VGA_Draw_LIN16_Line_HWMouse ) drawline_idx = 12;
  7309. + else if( VGA_DrawLine == VGA_Draw_LIN32_Line_HWMouse ) drawline_idx = 13;
  7310. + else if( VGA_DrawLine == VGA_TEXT_Draw_Line ) drawline_idx = 14;
  7311. + else if( VGA_DrawLine == VGA_TEXT_Herc_Draw_Line ) drawline_idx = 15;
  7312. + else if( VGA_DrawLine == VGA_TEXT_Xlat16_Draw_Line ) drawline_idx = 17;
  7313. +
  7314. + //**********************************************
  7315. + //**********************************************
  7316. +
  7317. + // - near-pure (struct) data
  7318. + WRITE_POD( &vga.draw, vga.draw );
  7319. +
  7320. +
  7321. + // - reloc ptr
  7322. + WRITE_POD( &linear_base_idx, linear_base_idx );
  7323. + WRITE_POD( &font_tables_idx, font_tables_idx );
  7324. +
  7325. + //**********************************************
  7326. + //**********************************************
  7327. +
  7328. + // static globals
  7329. +
  7330. + // - reloc function ptr
  7331. + WRITE_POD( &drawline_idx, drawline_idx );
  7332. +
  7333. +
  7334. + // - pure data
  7335. + WRITE_POD( &TempLine, TempLine );
  7336. +
  7337. +
  7338. + // - system data
  7339. + //WRITE_POD( &vsync, vsync );
  7340. + //WRITE_POD( &uservsyncjolt, uservsyncjolt );
  7341. +
  7342. +
  7343. + // - pure data
  7344. + WRITE_POD( &temp, temp );
  7345. + WRITE_POD( &FontMask, FontMask );
  7346. + WRITE_POD( &bg_color_index, bg_color_index );
  7347. +}
  7348. +
  7349. +
  7350. +void POD_Load_VGA_Draw( std::istream& stream )
  7351. +{
  7352. + Bit8u linear_base_idx;
  7353. + Bit8u font_tables_idx[2];
  7354. + Bit8u drawline_idx;
  7355. +
  7356. + //**********************************************
  7357. + //**********************************************
  7358. +
  7359. + // - near-pure (struct) data
  7360. + READ_POD( &vga.draw, vga.draw );
  7361. +
  7362. +
  7363. + // - reloc ptr
  7364. + READ_POD( &linear_base_idx, linear_base_idx );
  7365. + READ_POD( &font_tables_idx, font_tables_idx );
  7366. +
  7367. + //**********************************************
  7368. + //**********************************************
  7369. +
  7370. + // static globals
  7371. +
  7372. + // - reloc function ptr
  7373. + READ_POD( &drawline_idx, drawline_idx );
  7374. +
  7375. +
  7376. + // - pure data
  7377. + READ_POD( &TempLine, TempLine );
  7378. +
  7379. +
  7380. + // - system data
  7381. + //READ_POD( &vsync, vsync );
  7382. + //READ_POD( &uservsyncjolt, uservsyncjolt );
  7383. +
  7384. +
  7385. + // - pure data
  7386. + READ_POD( &temp, temp );
  7387. + READ_POD( &FontMask, FontMask );
  7388. + READ_POD( &bg_color_index, bg_color_index );
  7389. +
  7390. + //**********************************************
  7391. + //**********************************************
  7392. +
  7393. + switch( linear_base_idx ) {
  7394. + case 0: vga.draw.linear_base = vga.mem.linear; break;
  7395. + case 1: vga.draw.linear_base = vga.fastmem; break;
  7396. + }
  7397. +
  7398. +
  7399. + for( int lcv=0; lcv<2; lcv++ ) {
  7400. + switch( font_tables_idx[lcv] ) {
  7401. + case 0: vga.draw.font_tables[lcv] = &(vga.draw.font[0*1024]); break;
  7402. + case 1: vga.draw.font_tables[lcv] = &(vga.draw.font[8*1024]); break;
  7403. + case 2: vga.draw.font_tables[lcv] = &(vga.draw.font[16*1024]); break;
  7404. + case 3: vga.draw.font_tables[lcv] = &(vga.draw.font[24*1024]); break;
  7405. + case 4: vga.draw.font_tables[lcv] = &(vga.draw.font[32*1024]); break;
  7406. + case 5: vga.draw.font_tables[lcv] = &(vga.draw.font[40*1024]); break;
  7407. + case 6: vga.draw.font_tables[lcv] = &(vga.draw.font[48*1024]); break;
  7408. + case 7: vga.draw.font_tables[lcv] = &(vga.draw.font[56*1024]); break;
  7409. + }
  7410. + }
  7411. +
  7412. +
  7413. + switch( drawline_idx ) {
  7414. + case 1: VGA_DrawLine = VGA_Draw_1BPP_Line; break;
  7415. + case 3: VGA_DrawLine = VGA_Draw_2BPP_Line; break;
  7416. + case 4: VGA_DrawLine = VGA_Draw_2BPPHiRes_Line; break;
  7417. + case 5: VGA_DrawLine = VGA_Draw_CGA16_Line; break;
  7418. + case 6: VGA_DrawLine = VGA_Draw_4BPP_Line; break;
  7419. + case 7: VGA_DrawLine = VGA_Draw_4BPP_Line_Double; break;
  7420. + case 8: VGA_DrawLine = VGA_Draw_Linear_Line; break;
  7421. + case 9: VGA_DrawLine = VGA_Draw_Xlat16_Linear_Line; break;
  7422. + case 11: VGA_DrawLine = VGA_Draw_VGA_Line_HWMouse; break;
  7423. + case 12: VGA_DrawLine = VGA_Draw_LIN16_Line_HWMouse; break;
  7424. + case 13: VGA_DrawLine = VGA_Draw_LIN32_Line_HWMouse; break;
  7425. + case 14: VGA_DrawLine = VGA_TEXT_Draw_Line; break;
  7426. + case 15: VGA_DrawLine = VGA_TEXT_Herc_Draw_Line; break;
  7427. + case 17: VGA_DrawLine = VGA_TEXT_Xlat16_Draw_Line; break;
  7428. + }
  7429. +}
  7430. +
  7431. +/*
  7432. +ykhwong svn-daum 2012-02-20
  7433. +
  7434. +static globals:
  7435. +
  7436. +// - reloc function ptr
  7437. +static VGA_Line_Handler VGA_DrawLine;
  7438. +
  7439. +// - pure data
  7440. +static Bit8u TempLine[SCALER_MAXWIDTH * 4 + 256];
  7441. +
  7442. +
  7443. +// - system data
  7444. +static struct vsync
  7445. +- double period;
  7446. +- bool manual;
  7447. +- bool persistent;
  7448. +- bool faithful;
  7449. +
  7450. +
  7451. +// - system data
  7452. +static float uservsyncjolt;
  7453. +
  7454. +
  7455. +// - pure data
  7456. +static Bitu temp[643];
  7457. +static Bit32u FontMask[2];
  7458. +static Bit8u bg_color_index;
  7459. +
  7460. +
  7461. +
  7462. +
  7463. +struct VGA_Draw:
  7464. +
  7465. +typedef struct {
  7466. +// - pure data
  7467. + bool resizing;
  7468. + Bitu width;
  7469. + Bitu height;
  7470. + Bitu blocks;
  7471. + Bitu address;
  7472. + Bitu panning;
  7473. + Bitu bytes_skip;
  7474. +
  7475. +// - reloc ptr
  7476. + Bit8u *linear_base;
  7477. +
  7478. +// - pure data
  7479. + Bitu linear_mask;
  7480. + Bitu address_add;
  7481. + Bitu line_length;
  7482. + Bitu address_line_total;
  7483. + Bitu address_line;
  7484. + Bitu lines_total;
  7485. + Bitu vblank_skip;
  7486. + Bitu lines_done;
  7487. + Bitu split_line;
  7488. + Bitu parts_total;
  7489. + Bitu parts_lines;
  7490. + Bitu parts_left;
  7491. + Bitu byte_panning_shift;
  7492. +
  7493. +
  7494. +// - pure struct data
  7495. + struct {
  7496. + double framestart;
  7497. + double vrstart, vrend; // V-retrace
  7498. + double hrstart, hrend; // H-retrace
  7499. + double hblkstart, hblkend; // H-blanking
  7500. + double vblkstart, vblkend; // V-Blanking
  7501. + double vdend, vtotal;
  7502. + double hdend, htotal;
  7503. + double parts;
  7504. + float singleline_delay;
  7505. + } delay;
  7506. +
  7507. +
  7508. +// - pure data
  7509. + double screen_ratio;
  7510. + double refresh;
  7511. + bool doublescan_merging;
  7512. + Bit8u font[64*1024];
  7513. +
  7514. +// - reloc ptr
  7515. + Bit8u * font_tables[2];
  7516. +
  7517. +// - pure data
  7518. + Bitu blinking;
  7519. + bool blink;
  7520. + bool char9dot;
  7521. +
  7522. +
  7523. +// - pure struct data
  7524. + struct {
  7525. + Bitu address;
  7526. + Bit8u sline,eline;
  7527. + Bit8u count,delay;
  7528. + Bit8u enabled;
  7529. + } cursor;
  7530. +
  7531. +
  7532. +// - pure data
  7533. + Drawmode mode;
  7534. + bool vret_triggered;
  7535. + bool vga_override;
  7536. + bool linewise_set;
  7537. + bool linewise_effect;
  7538. + bool multiscan_set;
  7539. + bool multiscan_effect;
  7540. + bool char9_set;
  7541. + Bitu bpp;
  7542. +*/
  7543. Index: src/hardware/vga_gfx.cpp
  7544. ===================================================================
  7545. --- src/hardware/vga_gfx.cpp (revision 4176)
  7546. +++ src/hardware/vga_gfx.cpp (working copy)
  7547. @@ -21,6 +21,8 @@
  7548. #include "inout.h"
  7549. #include "vga.h"
  7550.  
  7551. +#include "../save_state.h"
  7552. +
  7553. #define gfx(blah) vga.gfx.blah
  7554. static bool index9warned=false;
  7555.  
  7556. @@ -232,4 +234,29 @@
  7557. }
  7558. }
  7559.  
  7560. +// save state support
  7561.  
  7562. +void POD_Save_VGA_Gfx( std::ostream& stream )
  7563. +{
  7564. + // - pure struct data
  7565. + WRITE_POD( &vga.gfx, vga.gfx );
  7566. +
  7567. + //*******************************************
  7568. + //*******************************************
  7569. +
  7570. + // - system data
  7571. + //WRITE_POD( &index9warned, index9warned );
  7572. +}
  7573. +
  7574. +
  7575. +void POD_Load_VGA_Gfx( std::istream& stream )
  7576. +{
  7577. + // - pure struct data
  7578. + READ_POD( &vga.gfx, vga.gfx );
  7579. +
  7580. + //*******************************************
  7581. + //*******************************************
  7582. +
  7583. + // - system data
  7584. + //READ_POD( &index9warned, index9warned );
  7585. +}
  7586. \ No newline at end of file
  7587. Index: src/hardware/vga_memory.cpp
  7588. ===================================================================
  7589. --- src/hardware/vga_memory.cpp (revision 4176)
  7590. +++ src/hardware/vga_memory.cpp (working copy)
  7591. @@ -27,7 +27,9 @@
  7592. #include "inout.h"
  7593. #include "setup.h"
  7594.  
  7595. +#include "../save_state.h"
  7596.  
  7597. +
  7598. #ifndef C_VGARAM_CHECKED
  7599. #define C_VGARAM_CHECKED 1
  7600. #endif
  7601. @@ -986,3 +988,69 @@
  7602. //TODO map?
  7603. }
  7604. }
  7605. +
  7606. +// save state support
  7607. +void *VGA_PageHandler_Func[16] =
  7608. +{
  7609. + (void *) &vgaph.map,
  7610. + (void *) &vgaph.changes,
  7611. + (void *) &vgaph.text,
  7612. + (void *) &vgaph.tandy,
  7613. + (void *) &vgaph.cega,
  7614. + (void *) &vgaph.cvga,
  7615. + (void *) &vgaph.uega,
  7616. + (void *) &vgaph.uvga,
  7617. + (void *) &vgaph.pcjr,
  7618. + (void *) &vgaph.herc,
  7619. + (void *) &vgaph.lin4,
  7620. + (void *) &vgaph.lfb,
  7621. + (void *) &vgaph.lfbchanges,
  7622. + (void *) &vgaph.mmio,
  7623. + (void *) &vgaph.empty,
  7624. +};
  7625. +
  7626. +
  7627. +void POD_Save_VGA_Memory( std::ostream& stream )
  7628. +{
  7629. + // - static ptrs
  7630. + //Bit8u* linear;
  7631. + //Bit8u* linear_orgptr;
  7632. +
  7633. +
  7634. + // - pure data
  7635. + WRITE_POD_SIZE( vga.mem.linear_orgptr, sizeof(Bit8u) * (std::max<Bit32u>(vga.vmemsize, 512 * 1024U) + 2048 + 16) );
  7636. +
  7637. + //***************************************************
  7638. + //***************************************************
  7639. +
  7640. + // static globals
  7641. +
  7642. + // - pure struct data
  7643. + WRITE_POD( &vgapages, vgapages );
  7644. +
  7645. + // - static classes
  7646. + //WRITE_POD( &vgaph, vgaph );
  7647. +}
  7648. +
  7649. +
  7650. +void POD_Load_VGA_Memory( std::istream& stream )
  7651. +{
  7652. + // - static ptrs
  7653. + //Bit8u* linear;
  7654. + //Bit8u* linear_orgptr;
  7655. +
  7656. +
  7657. + // - pure data
  7658. + READ_POD_SIZE( vga.mem.linear_orgptr, sizeof(Bit8u) * (std::max<Bit32u>(vga.vmemsize, 512 * 1024U) + 2048 + 16) );
  7659. +
  7660. + //***************************************************
  7661. + //***************************************************
  7662. +
  7663. + // static globals
  7664. +
  7665. + // - pure struct data
  7666. + READ_POD( &vgapages, vgapages );
  7667. +
  7668. + // - static classes
  7669. + //READ_POD( &vgaph, vgaph );
  7670. +}
  7671. \ No newline at end of file
  7672. Index: src/hardware/vga_other.cpp
  7673. ===================================================================
  7674. --- src/hardware/vga_other.cpp (revision 4176)
  7675. +++ src/hardware/vga_other.cpp (working copy)
  7676. @@ -27,6 +27,8 @@
  7677. #include "render.h"
  7678. #include "mapper.h"
  7679.  
  7680. +#include "../save_state.h"
  7681. +
  7682. static void write_crtc_index_other(Bitu /*port*/,Bitu val,Bitu /*iolen*/) {
  7683. vga.other.index=(Bit8u)val;
  7684. }
  7685. @@ -865,3 +867,38 @@
  7686. }
  7687.  
  7688. }
  7689. +
  7690. +// save state support
  7691. +
  7692. +void POD_Save_VGA_Other( std::ostream& stream )
  7693. +{
  7694. + // - pure struct data
  7695. + WRITE_POD( &vga.other, vga.other );
  7696. +
  7697. + //****************************************
  7698. + //****************************************
  7699. +
  7700. + // static globals
  7701. +
  7702. + // - system + user data
  7703. + WRITE_POD( &hue_offset, hue_offset );
  7704. + WRITE_POD( &cga16_val, cga16_val );
  7705. + WRITE_POD( &herc_pal, herc_pal );
  7706. +}
  7707. +
  7708. +
  7709. +void POD_Load_VGA_Other( std::istream& stream )
  7710. +{
  7711. + // - pure struct data
  7712. + READ_POD( &vga.other, vga.other );
  7713. +
  7714. + //****************************************
  7715. + //****************************************
  7716. +
  7717. + // static globals
  7718. +
  7719. + // - system + user data
  7720. + READ_POD( &hue_offset, hue_offset );
  7721. + READ_POD( &cga16_val, cga16_val );
  7722. + READ_POD( &herc_pal, herc_pal );
  7723. +}
  7724. \ No newline at end of file
  7725. Index: src/hardware/vga_paradise.cpp
  7726. ===================================================================
  7727. --- src/hardware/vga_paradise.cpp (revision 4176)
  7728. +++ src/hardware/vga_paradise.cpp (working copy)
  7729. @@ -23,6 +23,8 @@
  7730. #include "inout.h"
  7731. #include "mem.h"
  7732.  
  7733. +#include "../save_state.h"
  7734. +
  7735. typedef struct {
  7736. Bitu PR0A;
  7737. Bitu PR0B;
  7738. @@ -239,3 +241,24 @@
  7739.  
  7740. IO_Write(0x3cf, 0x05); // Enable!
  7741. }
  7742. +
  7743. +// save state support
  7744. +
  7745. +void POD_Save_VGA_Paradise( std::ostream& stream )
  7746. +{
  7747. + // static globals
  7748. +
  7749. +
  7750. + // - pure struct data
  7751. + WRITE_POD( &pvga1a, pvga1a );
  7752. +}
  7753. +
  7754. +
  7755. +void POD_Load_VGA_Paradise( std::istream& stream )
  7756. +{
  7757. + // static globals
  7758. +
  7759. +
  7760. + // - pure struct data
  7761. + READ_POD( &pvga1a, pvga1a );
  7762. +}
  7763. \ No newline at end of file
  7764. Index: src/hardware/vga_s3.cpp
  7765. ===================================================================
  7766. --- src/hardware/vga_s3.cpp (revision 4176)
  7767. +++ src/hardware/vga_s3.cpp (working copy)
  7768. @@ -22,6 +22,8 @@
  7769. #include "vga.h"
  7770. #include "mem.h"
  7771.  
  7772. +#include "../save_state.h"
  7773. +
  7774. void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen) {
  7775. switch (reg) {
  7776. case 0x31: /* CR31 Memory Configuration */
  7777. @@ -563,3 +565,28 @@
  7778. phys_writeb(rom_base+0x0046,'6');
  7779. phys_writeb(rom_base+0x0047,'4');
  7780. }
  7781. +
  7782. +// save state support
  7783. +
  7784. +void POD_Save_VGA_S3( std::ostream& stream )
  7785. +{
  7786. + // - pure struct data
  7787. + WRITE_POD( &vga.s3, vga.s3 );
  7788. +
  7789. + //*****************************************
  7790. + //*****************************************
  7791. +
  7792. + // static globals
  7793. +}
  7794. +
  7795. +
  7796. +void POD_Load_VGA_S3( std::istream& stream )
  7797. +{
  7798. + // - pure struct data
  7799. + READ_POD( &vga.s3, vga.s3 );
  7800. +
  7801. + //*****************************************
  7802. + //*****************************************
  7803. +
  7804. + // static globals
  7805. +}
  7806. \ No newline at end of file
  7807. Index: src/hardware/vga_seq.cpp
  7808. ===================================================================
  7809. --- src/hardware/vga_seq.cpp (revision 4176)
  7810. +++ src/hardware/vga_seq.cpp (working copy)
  7811. @@ -21,6 +21,8 @@
  7812. #include "inout.h"
  7813. #include "vga.h"
  7814.  
  7815. +#include "../save_state.h"
  7816. +
  7817. #define seq(blah) vga.seq.blah
  7818.  
  7819. Bitu read_p3c4(Bitu /*port*/,Bitu /*iolen*/) {
  7820. @@ -158,3 +160,41 @@
  7821. }
  7822. }
  7823.  
  7824. +// save state support
  7825. +
  7826. +void POD_Save_VGA_Seq( std::ostream& stream )
  7827. +{
  7828. + // - pure struct data
  7829. + WRITE_POD( &vga.seq, vga.seq );
  7830. +
  7831. +
  7832. + // no static globals found
  7833. +}
  7834. +
  7835. +
  7836. +void POD_Load_VGA_Seq( std::istream& stream )
  7837. +{
  7838. + // - pure struct data
  7839. + READ_POD( &vga.seq, vga.seq );
  7840. +
  7841. +
  7842. + // no static globals found
  7843. +}
  7844. +
  7845. +
  7846. +/*
  7847. +ykhwong svn-daum 2012-02-20
  7848. +
  7849. +static globals: none
  7850. +
  7851. +
  7852. +struct VGA_Seq:
  7853. +
  7854. +// - pure data
  7855. + Bit8u index;
  7856. + Bit8u reset;
  7857. + Bit8u clocking_mode;
  7858. + Bit8u map_mask;
  7859. + Bit8u character_map_select;
  7860. + Bit8u memory_mode;
  7861. +*/
  7862. \ No newline at end of file
  7863. Index: src/hardware/vga_tseng.cpp
  7864. ===================================================================
  7865. --- src/hardware/vga_tseng.cpp (revision 4176)
  7866. +++ src/hardware/vga_tseng.cpp (working copy)
  7867. @@ -24,6 +24,9 @@
  7868. #include "inout.h"
  7869. #include "mem.h"
  7870. #include <cstdlib>
  7871. +
  7872. +#include "../save_state.h"
  7873. +
  7874. // Tseng ET4K data
  7875. typedef struct {
  7876. Bit8u extensionsEnabled;
  7877. @@ -805,3 +808,26 @@
  7878. phys_writeb(rom_base+0x007a,'g');
  7879. phys_writeb(rom_base+0x007b,' ');
  7880. }
  7881. +
  7882. +// save state support
  7883. +
  7884. +void POD_Save_VGA_Tseng( std::ostream& stream )
  7885. +{
  7886. + // static globals
  7887. +
  7888. +
  7889. + // - pure struct data
  7890. + WRITE_POD( &et4k, et4k );
  7891. + WRITE_POD( &et3k, et3k );
  7892. +}
  7893. +
  7894. +
  7895. +void POD_Load_VGA_Tseng( std::istream& stream )
  7896. +{
  7897. + // static globals
  7898. +
  7899. +
  7900. + // - pure struct data
  7901. + READ_POD( &et4k, et4k );
  7902. + READ_POD( &et3k, et3k );
  7903. +}
  7904. \ No newline at end of file
  7905. Index: src/hardware/vga_xga.cpp
  7906. ===================================================================
  7907. --- src/hardware/vga_xga.cpp (revision 4176)
  7908. +++ src/hardware/vga_xga.cpp (working copy)
  7909. @@ -26,6 +26,8 @@
  7910. #include "callback.h"
  7911. #include "cpu.h" // for 0x3da delay
  7912.  
  7913. +#include "../save_state.h"
  7914. +
  7915. #define XGA_SCREEN_WIDTH vga.s3.xga_screen_width
  7916. #define XGA_COLOR_MODE vga.s3.xga_color_mode
  7917.  
  7918. @@ -1317,3 +1319,24 @@
  7919. IO_RegisterWriteHandler(0xe2ea,&XGA_Write,IO_MB | IO_MW | IO_MD);
  7920. IO_RegisterReadHandler(0xe2ea,&XGA_Read,IO_MB | IO_MW | IO_MD);
  7921. }
  7922. +
  7923. +// save state support
  7924. +
  7925. +void POD_Save_VGA_XGA( std::ostream& stream )
  7926. +{
  7927. + // static globals
  7928. +
  7929. +
  7930. + // - pure struct data
  7931. + WRITE_POD( &xga, xga );
  7932. +}
  7933. +
  7934. +
  7935. +void POD_Load_VGA_XGA( std::istream& stream )
  7936. +{
  7937. + // static globals
  7938. +
  7939. +
  7940. + // - pure struct data
  7941. + READ_POD( &xga, xga );
  7942. +}
  7943. \ No newline at end of file
  7944. Index: src/ints/ems.cpp
  7945. ===================================================================
  7946. --- src/ints/ems.cpp (revision 4176)
  7947. +++ src/ints/ems.cpp (working copy)
  7948. @@ -31,6 +31,9 @@
  7949. #include "setup.h"
  7950. #include "support.h"
  7951. #include "cpu.h"
  7952. +
  7953. +#include "../save_state.h"
  7954. +
  7955. #include "dma.h"
  7956.  
  7957. #define EMM_PAGEFRAME 0xE000
  7958. @@ -1469,3 +1472,25 @@
  7959.  
  7960. //Initialize static members
  7961. Bit16u EMS::ems_baseseg = 0;
  7962. +
  7963. +//save state support
  7964. +namespace
  7965. +{
  7966. +class SerializeEMS : public SerializeGlobalPOD
  7967. +{
  7968. +public:
  7969. + SerializeEMS() : SerializeGlobalPOD("EMS")
  7970. + {
  7971. + registerPOD(emm_handles);
  7972. + registerPOD(emm_mappings);
  7973. + registerPOD(emm_segmentmappings);
  7974. + registerPOD(GEMMIS_seg);
  7975. + registerPOD(vcpi.enabled);
  7976. + registerPOD(vcpi.ems_handle);
  7977. + registerPOD(vcpi.pm_interface);
  7978. + registerPOD(vcpi.private_area);
  7979. + registerPOD(vcpi.pic1_remapping);
  7980. + registerPOD(vcpi.pic2_remapping);
  7981. + }
  7982. +} dummy;
  7983. +}
  7984. \ No newline at end of file
  7985. Index: src/ints/int10.cpp
  7986. ===================================================================
  7987. --- src/ints/int10.cpp (revision 4176)
  7988. +++ src/ints/int10.cpp (working copy)
  7989. @@ -26,6 +26,8 @@
  7990. #include "mouse.h"
  7991. #include "setup.h"
  7992.  
  7993. +#include "../save_state.h"
  7994. +
  7995. Int10Data int10;
  7996. static Bitu call_10;
  7997. static bool warned_ff=false;
  7998. @@ -767,3 +769,24 @@
  7999. INT10_Seg40Init();
  8000. INT10_SetVideoMode(0x3);
  8001. }
  8002. +
  8003. +//save state support
  8004. +namespace
  8005. +{
  8006. +class SerializeInt10 : public SerializeGlobalPOD
  8007. +{
  8008. +public:
  8009. + SerializeInt10() : SerializeGlobalPOD("Int10")
  8010. + {
  8011. + registerPOD(int10);
  8012. + //registerPOD(CurMode);
  8013. + //registerPOD(call_10);
  8014. + //registerPOD(warned_ff);
  8015. + }
  8016. +
  8017. + // virtual void setBytes(std::istream& stream)
  8018. + //{
  8019. + // SerializeGlobalPOD::setBytes(stream);
  8020. + //}
  8021. +} dummy;
  8022. +}
  8023. \ No newline at end of file
  8024. Index: src/ints/mouse.cpp
  8025. ===================================================================
  8026. --- src/ints/mouse.cpp (revision 4176)
  8027. +++ src/ints/mouse.cpp (working copy)
  8028. @@ -33,6 +33,8 @@
  8029. #include "bios.h"
  8030. #include "dos_inc.h"
  8031.  
  8032. +#include "../save_state.h"
  8033. +
  8034. static Bitu call_int33,call_int74,int74_ret_callback,call_mouse_bd;
  8035. static Bit16u ps2cbseg,ps2cbofs;
  8036. static bool useps2callback,ps2callbackinit;
  8037. @@ -1143,3 +1145,118 @@
  8038. Mouse_Reset();
  8039. Mouse_SetSensitivity(50,50,50);
  8040. }
  8041. +
  8042. +//save state support
  8043. +void *MOUSE_Limit_Events_PIC_Event = (void*)MOUSE_Limit_Events;
  8044. +
  8045. +
  8046. +namespace
  8047. +{
  8048. +class SerializeMouse : public SerializeGlobalPOD
  8049. +{
  8050. +public:
  8051. + SerializeMouse() : SerializeGlobalPOD("Mouse")
  8052. + {}
  8053. +
  8054. +private:
  8055. + virtual void getBytes(std::ostream& stream)
  8056. + {
  8057. + Bit8u screenMask_idx, cursorMask_idx;
  8058. +
  8059. +
  8060. + if( mouse.screenMask == defaultScreenMask ) screenMask_idx = 0x00;
  8061. + else if( mouse.screenMask == userdefScreenMask ) screenMask_idx = 0x01;
  8062. +
  8063. + if( mouse.cursorMask == defaultCursorMask ) cursorMask_idx = 0x00;
  8064. + else if( mouse.cursorMask == userdefCursorMask ) cursorMask_idx = 0x01;
  8065. +
  8066. + //*******************************************
  8067. + //*******************************************
  8068. + //*******************************************
  8069. +
  8070. + SerializeGlobalPOD::getBytes(stream);
  8071. +
  8072. +
  8073. + // - pure data
  8074. + WRITE_POD( &ps2cbseg, ps2cbseg );
  8075. + WRITE_POD( &ps2cbofs, ps2cbofs );
  8076. + WRITE_POD( &useps2callback, useps2callback );
  8077. + WRITE_POD( &ps2callbackinit, ps2callbackinit );
  8078. +
  8079. + WRITE_POD( &userdefScreenMask, userdefScreenMask );
  8080. + WRITE_POD( &userdefCursorMask, userdefCursorMask );
  8081. +
  8082. +
  8083. + // - near-pure data
  8084. + WRITE_POD( &mouse, mouse );
  8085. +
  8086. +
  8087. + // - pure data
  8088. + WRITE_POD( &gfxReg3CE, gfxReg3CE );
  8089. + WRITE_POD( &index3C4, index3C4 );
  8090. + WRITE_POD( &gfxReg3C5, gfxReg3C5 );
  8091. +
  8092. + //*******************************************
  8093. + //*******************************************
  8094. + //*******************************************
  8095. +
  8096. + // - reloc ptr
  8097. + WRITE_POD( &screenMask_idx, screenMask_idx );
  8098. + WRITE_POD( &cursorMask_idx, cursorMask_idx );
  8099. + }
  8100. +
  8101. + virtual void setBytes(std::istream& stream)
  8102. + {
  8103. + Bit8u screenMask_idx, cursorMask_idx;
  8104. +
  8105. + //*******************************************
  8106. + //*******************************************
  8107. + //*******************************************
  8108. +
  8109. + SerializeGlobalPOD::setBytes(stream);
  8110. +
  8111. +
  8112. + // - pure data
  8113. + READ_POD( &ps2cbseg, ps2cbseg );
  8114. + READ_POD( &ps2cbofs, ps2cbofs );
  8115. + READ_POD( &useps2callback, useps2callback );
  8116. + READ_POD( &ps2callbackinit, ps2callbackinit );
  8117. +
  8118. + READ_POD( &userdefScreenMask, userdefScreenMask );
  8119. + READ_POD( &userdefCursorMask, userdefCursorMask );
  8120. +
  8121. +
  8122. + // - near-pure data
  8123. + READ_POD( &mouse, mouse );
  8124. +
  8125. +
  8126. + // - pure data
  8127. + READ_POD( &gfxReg3CE, gfxReg3CE );
  8128. + READ_POD( &index3C4, index3C4 );
  8129. + READ_POD( &gfxReg3C5, gfxReg3C5 );
  8130. +
  8131. + //*******************************************
  8132. + //*******************************************
  8133. + //*******************************************
  8134. +
  8135. + // - reloc ptr
  8136. + READ_POD( &screenMask_idx, screenMask_idx );
  8137. + READ_POD( &cursorMask_idx, cursorMask_idx );
  8138. +
  8139. +
  8140. + if( screenMask_idx == 0x00 ) mouse.screenMask = defaultScreenMask;
  8141. + else if( screenMask_idx == 0x01 ) mouse.screenMask = userdefScreenMask;
  8142. +
  8143. + if( cursorMask_idx == 0x00 ) mouse.cursorMask = defaultCursorMask;
  8144. + else if( cursorMask_idx == 0x01 ) mouse.cursorMask = userdefCursorMask;
  8145. +
  8146. + //*******************************************
  8147. + //*******************************************
  8148. + //*******************************************
  8149. +
  8150. + // reset
  8151. + oldmouseX = static_cast<Bit16s>(mouse.x);
  8152. + oldmouseY = static_cast<Bit16s>(mouse.y);
  8153. + }
  8154. +} dummy;
  8155. +}
  8156. \ No newline at end of file
  8157. Index: src/ints/xms.cpp
  8158. ===================================================================
  8159. --- src/ints/xms.cpp (revision 4176)
  8160. +++ src/ints/xms.cpp (working copy)
  8161. @@ -30,6 +30,8 @@
  8162. #include "xms.h"
  8163. #include "bios.h"
  8164.  
  8165. +#include "../save_state.h"
  8166. +
  8167. #define XMS_HANDLES 50 /* 50 XMS Memory Blocks */
  8168. #define XMS_VERSION 0x0300 /* version 3.00 */
  8169. #define XMS_DRIVER_VERSION 0x0301 /* my driver version 3.01 */
  8170. @@ -483,3 +485,16 @@
  8171. test = new XMS(sec);
  8172. sec->AddDestroyFunction(&XMS_ShutDown,true);
  8173. }
  8174. +
  8175. +//save state support
  8176. + namespace
  8177. +{
  8178. +class SerializeXMS : public SerializeGlobalPOD
  8179. +{
  8180. +public:
  8181. + SerializeXMS() : SerializeGlobalPOD("XMS")
  8182. + {
  8183. + registerPOD(xms_handles);
  8184. + }
  8185. +} dummy;
  8186. +}
  8187. \ No newline at end of file
  8188. Index: src/ioapi.c
  8189. ===================================================================
  8190. --- src/ioapi.c (nonexistent)
  8191. +++ src/ioapi.c (working copy)
  8192. @@ -0,0 +1,235 @@
  8193. +/* ioapi.h -- IO base function header for compress/uncompress .zip
  8194. + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
  8195. +
  8196. + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
  8197. +
  8198. + Modifications for Zip64 support
  8199. + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
  8200. +
  8201. + For more info read MiniZip_info.txt
  8202. +
  8203. +*/
  8204. +
  8205. +#if (defined(_WIN32))
  8206. + #define _CRT_SECURE_NO_WARNINGS
  8207. +#endif
  8208. +
  8209. +#include "ioapi.h"
  8210. +
  8211. +voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)
  8212. +{
  8213. + if (pfilefunc->zfile_func64.zopen64_file != NULL)
  8214. + return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,filename,mode);
  8215. + else
  8216. + {
  8217. + return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,(const char*)filename,mode);
  8218. + }
  8219. +}
  8220. +
  8221. +long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)
  8222. +{
  8223. + if (pfilefunc->zfile_func64.zseek64_file != NULL)
  8224. + return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin);
  8225. + else
  8226. + {
  8227. + uLong offsetTruncated = (uLong)offset;
  8228. + if (offsetTruncated != offset)
  8229. + return -1;
  8230. + else
  8231. + return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin);
  8232. + }
  8233. +}
  8234. +
  8235. +ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)
  8236. +{
  8237. + if (pfilefunc->zfile_func64.zseek64_file != NULL)
  8238. + return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream);
  8239. + else
  8240. + {
  8241. + uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream);
  8242. + if ((tell_uLong) == ((uLong)-1))
  8243. + return (ZPOS64_T)-1;
  8244. + else
  8245. + return tell_uLong;
  8246. + }
  8247. +}
  8248. +
  8249. +void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32)
  8250. +{
  8251. + p_filefunc64_32->zfile_func64.zopen64_file = NULL;
  8252. + p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file;
  8253. + p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
  8254. + p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file;
  8255. + p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file;
  8256. + p_filefunc64_32->zfile_func64.ztell64_file = NULL;
  8257. + p_filefunc64_32->zfile_func64.zseek64_file = NULL;
  8258. + p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file;
  8259. + p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
  8260. + p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque;
  8261. + p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file;
  8262. + p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file;
  8263. +}
  8264. +
  8265. +
  8266. +
  8267. +static voidpf ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode));
  8268. +static uLong ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size));
  8269. +static uLong ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf,uLong size));
  8270. +static ZPOS64_T ZCALLBACK ftell64_file_func OF((voidpf opaque, voidpf stream));
  8271. +static long ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
  8272. +static int ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream));
  8273. +static int ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream));
  8274. +
  8275. +static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode)
  8276. +{
  8277. + FILE* file = NULL;
  8278. + const char* mode_fopen = NULL;
  8279. + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
  8280. + mode_fopen = "rb";
  8281. + else
  8282. + if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
  8283. + mode_fopen = "r+b";
  8284. + else
  8285. + if (mode & ZLIB_FILEFUNC_MODE_CREATE)
  8286. + mode_fopen = "wb";
  8287. +
  8288. + if ((filename!=NULL) && (mode_fopen != NULL))
  8289. + file = fopen(filename, mode_fopen);
  8290. + return file;
  8291. +}
  8292. +
  8293. +static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode)
  8294. +{
  8295. + FILE* file = NULL;
  8296. + const char* mode_fopen = NULL;
  8297. + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
  8298. + mode_fopen = "rb";
  8299. + else
  8300. + if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
  8301. + mode_fopen = "r+b";
  8302. + else
  8303. + if (mode & ZLIB_FILEFUNC_MODE_CREATE)
  8304. + mode_fopen = "wb";
  8305. +
  8306. + if ((filename!=NULL) && (mode_fopen != NULL))
  8307. + file = fopen64((const char*)filename, mode_fopen);
  8308. + return file;
  8309. +}
  8310. +
  8311. +
  8312. +static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size)
  8313. +{
  8314. + uLong ret;
  8315. + ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream);
  8316. + return ret;
  8317. +}
  8318. +
  8319. +static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size)
  8320. +{
  8321. + uLong ret;
  8322. + ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream);
  8323. + return ret;
  8324. +}
  8325. +
  8326. +static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream)
  8327. +{
  8328. + long ret;
  8329. + ret = ftell((FILE *)stream);
  8330. + return ret;
  8331. +}
  8332. +
  8333. +
  8334. +static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream)
  8335. +{
  8336. + ZPOS64_T ret;
  8337. + ret = ftello64((FILE *)stream);
  8338. + return ret;
  8339. +}
  8340. +
  8341. +static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offset, int origin)
  8342. +{
  8343. + int fseek_origin=0;
  8344. + long ret;
  8345. + switch (origin)
  8346. + {
  8347. + case ZLIB_FILEFUNC_SEEK_CUR :
  8348. + fseek_origin = SEEK_CUR;
  8349. + break;
  8350. + case ZLIB_FILEFUNC_SEEK_END :
  8351. + fseek_origin = SEEK_END;
  8352. + break;
  8353. + case ZLIB_FILEFUNC_SEEK_SET :
  8354. + fseek_origin = SEEK_SET;
  8355. + break;
  8356. + default: return -1;
  8357. + }
  8358. + ret = 0;
  8359. + if (fseek((FILE *)stream, offset, fseek_origin) != 0)
  8360. + ret = -1;
  8361. + return ret;
  8362. +}
  8363. +
  8364. +static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)
  8365. +{
  8366. + int fseek_origin=0;
  8367. + long ret;
  8368. + switch (origin)
  8369. + {
  8370. + case ZLIB_FILEFUNC_SEEK_CUR :
  8371. + fseek_origin = SEEK_CUR;
  8372. + break;
  8373. + case ZLIB_FILEFUNC_SEEK_END :
  8374. + fseek_origin = SEEK_END;
  8375. + break;
  8376. + case ZLIB_FILEFUNC_SEEK_SET :
  8377. + fseek_origin = SEEK_SET;
  8378. + break;
  8379. + default: return -1;
  8380. + }
  8381. + ret = 0;
  8382. +
  8383. + if(fseeko64((FILE *)stream, offset, fseek_origin) != 0)
  8384. + ret = -1;
  8385. +
  8386. + return ret;
  8387. +}
  8388. +
  8389. +
  8390. +static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream)
  8391. +{
  8392. + int ret;
  8393. + ret = fclose((FILE *)stream);
  8394. + return ret;
  8395. +}
  8396. +
  8397. +static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream)
  8398. +{
  8399. + int ret;
  8400. + ret = ferror((FILE *)stream);
  8401. + return ret;
  8402. +}
  8403. +
  8404. +void fill_fopen_filefunc (pzlib_filefunc_def)
  8405. + zlib_filefunc_def* pzlib_filefunc_def;
  8406. +{
  8407. + pzlib_filefunc_def->zopen_file = fopen_file_func;
  8408. + pzlib_filefunc_def->zread_file = fread_file_func;
  8409. + pzlib_filefunc_def->zwrite_file = fwrite_file_func;
  8410. + pzlib_filefunc_def->ztell_file = ftell_file_func;
  8411. + pzlib_filefunc_def->zseek_file = fseek_file_func;
  8412. + pzlib_filefunc_def->zclose_file = fclose_file_func;
  8413. + pzlib_filefunc_def->zerror_file = ferror_file_func;
  8414. + pzlib_filefunc_def->opaque = NULL;
  8415. +}
  8416. +
  8417. +void fill_fopen64_filefunc (zlib_filefunc64_def* pzlib_filefunc_def)
  8418. +{
  8419. + pzlib_filefunc_def->zopen64_file = fopen64_file_func;
  8420. + pzlib_filefunc_def->zread_file = fread_file_func;
  8421. + pzlib_filefunc_def->zwrite_file = fwrite_file_func;
  8422. + pzlib_filefunc_def->ztell64_file = ftell64_file_func;
  8423. + pzlib_filefunc_def->zseek64_file = fseek64_file_func;
  8424. + pzlib_filefunc_def->zclose_file = fclose_file_func;
  8425. + pzlib_filefunc_def->zerror_file = ferror_file_func;
  8426. + pzlib_filefunc_def->opaque = NULL;
  8427. +}
  8428. Index: src/miniunz.c
  8429. ===================================================================
  8430. --- src/miniunz.c (nonexistent)
  8431. +++ src/miniunz.c (working copy)
  8432. @@ -0,0 +1,514 @@
  8433. +/*
  8434. + miniunz.c
  8435. + Version 1.1, February 14h, 2010
  8436. + sample part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
  8437. +
  8438. + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
  8439. +
  8440. + Modifications of Unzip for Zip64
  8441. + Copyright (C) 2007-2008 Even Rouault
  8442. +
  8443. + Modifications for Zip64 support on both zip and unzip
  8444. + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
  8445. +*/
  8446. +
  8447. +#ifndef _WIN32
  8448. + #ifndef __USE_FILE_OFFSET64
  8449. + #define __USE_FILE_OFFSET64
  8450. + #endif
  8451. + #ifndef __USE_LARGEFILE64
  8452. + #define __USE_LARGEFILE64
  8453. + #endif
  8454. + #ifndef _LARGEFILE64_SOURCE
  8455. + #define _LARGEFILE64_SOURCE
  8456. + #endif
  8457. + #ifndef _FILE_OFFSET_BIT
  8458. + #define _FILE_OFFSET_BIT 64
  8459. + #endif
  8460. +#endif
  8461. +
  8462. +#include <stdio.h>
  8463. +#include <stdlib.h>
  8464. +#include <string.h>
  8465. +#include <time.h>
  8466. +#include <errno.h>
  8467. +#include <fcntl.h>
  8468. +
  8469. +#ifdef unix
  8470. +# include <unistd.h>
  8471. +# include <utime.h>
  8472. +#elif __APPLE__
  8473. +#else
  8474. +# include <direct.h>
  8475. +# include <io.h>
  8476. +#endif
  8477. +
  8478. +#include "unzip.h"
  8479. +
  8480. +#define CASESENSITIVITY (0)
  8481. +#define WRITEBUFFERSIZE (8192)
  8482. +#define MAXFILENAME (256)
  8483. +
  8484. +#ifdef _WIN32
  8485. +#define USEWIN32IOAPI
  8486. +#include "iowin32.h"
  8487. +#endif
  8488. +/*
  8489. + mini unzip, demo of unzip package
  8490. +
  8491. + usage :
  8492. + Usage : miniunz [-exvlo] file.zip [file_to_extract] [-d extractdir]
  8493. +
  8494. + list the file in the zipfile, and print the content of FILE_ID.ZIP or README.TXT
  8495. + if it exists
  8496. +*/
  8497. +
  8498. +
  8499. +/* change_file_date : change the date/time of a file
  8500. + filename : the filename of the file where date/time must be modified
  8501. + dosdate : the new date at the MSDos format (4 bytes)
  8502. + tmu_date : the SAME new date at the tm_unz format */
  8503. +void change_file_date(filename,dosdate,tmu_date)
  8504. + const char *filename;
  8505. + uLong dosdate;
  8506. + tm_unz tmu_date;
  8507. +{
  8508. +#ifdef _WIN32
  8509. + HANDLE hFile;
  8510. + FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite;
  8511. +
  8512. + hFile = CreateFileA(filename,GENERIC_READ | GENERIC_WRITE,
  8513. + 0,NULL,OPEN_EXISTING,0,NULL);
  8514. + GetFileTime(hFile,&ftCreate,&ftLastAcc,&ftLastWrite);
  8515. + DosDateTimeToFileTime((WORD)(dosdate>>16),(WORD)dosdate,&ftLocal);
  8516. + LocalFileTimeToFileTime(&ftLocal,&ftm);
  8517. + SetFileTime(hFile,&ftm,&ftLastAcc,&ftm);
  8518. + CloseHandle(hFile);
  8519. +#else
  8520. +#ifdef unix
  8521. + struct utimbuf ut;
  8522. + struct tm newdate;
  8523. + newdate.tm_sec = tmu_date.tm_sec;
  8524. + newdate.tm_min=tmu_date.tm_min;
  8525. + newdate.tm_hour=tmu_date.tm_hour;
  8526. + newdate.tm_mday=tmu_date.tm_mday;
  8527. + newdate.tm_mon=tmu_date.tm_mon;
  8528. + if (tmu_date.tm_year > 1900)
  8529. + newdate.tm_year=tmu_date.tm_year - 1900;
  8530. + else
  8531. + newdate.tm_year=tmu_date.tm_year ;
  8532. + newdate.tm_isdst=-1;
  8533. +
  8534. + ut.actime=ut.modtime=mktime(&newdate);
  8535. + utime(filename,&ut);
  8536. +#endif
  8537. +#endif
  8538. +}
  8539. +
  8540. +
  8541. +/* mymkdir and change_file_date are not 100 % portable
  8542. + As I don't know well Unix, I wait feedback for the unix portion */
  8543. +
  8544. +int mymkdir(dirname)
  8545. + const char* dirname;
  8546. +{
  8547. + int ret=0;
  8548. +#ifdef _WIN32
  8549. + ret = _mkdir(dirname);
  8550. +#else
  8551. +#ifdef unix
  8552. + ret = mkdir (dirname,0775);
  8553. +#endif
  8554. +#endif
  8555. + return ret;
  8556. +}
  8557. +
  8558. +int makedir (newdir)
  8559. + char *newdir;
  8560. +{
  8561. + char *buffer ;
  8562. + char *p;
  8563. + int len = (int)strlen(newdir);
  8564. +
  8565. + if (len <= 0)
  8566. + return 0;
  8567. +
  8568. + buffer = (char*)malloc(len+1);
  8569. + if (buffer==NULL)
  8570. + {
  8571. + //printf("Error allocating memory\n");
  8572. + return UNZ_INTERNALERROR;
  8573. + }
  8574. + strcpy(buffer,newdir);
  8575. +
  8576. + if (buffer[len-1] == '/') {
  8577. + buffer[len-1] = '\0';
  8578. + }
  8579. + if (mymkdir(buffer) == 0)
  8580. + {
  8581. + free(buffer);
  8582. + return 1;
  8583. + }
  8584. +
  8585. + p = buffer+1;
  8586. + while (1)
  8587. + {
  8588. + char hold;
  8589. +
  8590. + while(*p && *p != '\\' && *p != '/')
  8591. + p++;
  8592. + hold = *p;
  8593. + *p = 0;
  8594. + if ((mymkdir(buffer) == -1) && (errno == ENOENT))
  8595. + {
  8596. + //printf("couldn't create directory %s\n",buffer);
  8597. + free(buffer);
  8598. + return 0;
  8599. + }
  8600. + if (hold == 0)
  8601. + break;
  8602. + *p++ = hold;
  8603. + }
  8604. + free(buffer);
  8605. + return 1;
  8606. +}
  8607. +
  8608. +/*
  8609. +void do_help()
  8610. +{
  8611. + printf("Usage : miniunz [-e] [-x] [-v] [-l] [-o] [-p password] file.zip [file_to_extr.] [-d extractdir]\n\n" \
  8612. + " -e Extract without pathname (junk paths)\n" \
  8613. + " -x Extract with pathname\n" \
  8614. + " -v list files\n" \
  8615. + " -l list files\n" \
  8616. + " -d directory to extract into\n" \
  8617. + " -o overwrite files without prompting\n" \
  8618. + " -p extract crypted file using password\n\n");
  8619. +}
  8620. +*/
  8621. +void Display64BitsSize(ZPOS64_T n, int size_char)
  8622. +{
  8623. + /* to avoid compatibility problem , we do here the conversion */
  8624. + char number[21];
  8625. + int offset=19;
  8626. + int pos_string = 19;
  8627. + number[20]=0;
  8628. + for (;;) {
  8629. + number[offset]=(char)((n%10)+'0');
  8630. + if (number[offset] != '0')
  8631. + pos_string=offset;
  8632. + n/=10;
  8633. + if (offset==0)
  8634. + break;
  8635. + offset--;
  8636. + }
  8637. + {
  8638. + int size_display_string = 19-pos_string;
  8639. + while (size_char > size_display_string)
  8640. + {
  8641. + size_char--;
  8642. + //printf(" ");
  8643. + }
  8644. + }
  8645. +
  8646. + //printf("%s",&number[pos_string]);
  8647. +}
  8648. +
  8649. +int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password)
  8650. + unzFile uf;
  8651. + const int* popt_extract_without_path;
  8652. + int* popt_overwrite;
  8653. + const char* password;
  8654. +{
  8655. + char filename_inzip[256];
  8656. + char* filename_withoutpath;
  8657. + char* p;
  8658. + int err=UNZ_OK;
  8659. + FILE *fout=NULL;
  8660. + void* buf;
  8661. + uInt size_buf;
  8662. +
  8663. + unz_file_info64 file_info;
  8664. + uLong ratio=0;
  8665. + err = unzGetCurrentFileInfo64(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
  8666. +
  8667. + if (err!=UNZ_OK)
  8668. + {
  8669. + //printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
  8670. + return err;
  8671. + }
  8672. +
  8673. + size_buf = WRITEBUFFERSIZE;
  8674. + buf = (void*)malloc(size_buf);
  8675. + if (buf==NULL)
  8676. + {
  8677. + //printf("Error allocating memory\n");
  8678. + return UNZ_INTERNALERROR;
  8679. + }
  8680. +
  8681. + p = filename_withoutpath = filename_inzip;
  8682. + while ((*p) != '\0')
  8683. + {
  8684. + if (((*p)=='/') || ((*p)=='\\'))
  8685. + filename_withoutpath = p+1;
  8686. + p++;
  8687. + }
  8688. +
  8689. + if ((*filename_withoutpath)=='\0')
  8690. + {
  8691. + if ((*popt_extract_without_path)==0)
  8692. + {
  8693. + //printf("creating directory: %s\n",filename_inzip);
  8694. + mymkdir(filename_inzip);
  8695. + }
  8696. + }
  8697. + else
  8698. + {
  8699. + const char* write_filename;
  8700. + int skip=0;
  8701. +
  8702. + if ((*popt_extract_without_path)==0)
  8703. + write_filename = filename_inzip;
  8704. + else
  8705. + write_filename = filename_withoutpath;
  8706. +
  8707. + err = unzOpenCurrentFilePassword(uf,password);
  8708. + if (err!=UNZ_OK)
  8709. + {
  8710. + //printf("error %d with zipfile in unzOpenCurrentFilePassword\n",err);
  8711. + }
  8712. +
  8713. + if (((*popt_overwrite)==0) && (err==UNZ_OK))
  8714. + {
  8715. + char rep=0;
  8716. + FILE* ftestexist;
  8717. + ftestexist = fopen64(write_filename,"rb");
  8718. + if (ftestexist!=NULL)
  8719. + {
  8720. + fclose(ftestexist);
  8721. + do
  8722. + {
  8723. + char answer[128];
  8724. + int ret;
  8725. +
  8726. + //printf("The file %s exists. Overwrite ? [y]es, [n]o, [A]ll: ",write_filename);
  8727. + ret = scanf("%1s",answer);
  8728. + if (ret != 1)
  8729. + {
  8730. + exit(EXIT_FAILURE);
  8731. + }
  8732. + rep = answer[0] ;
  8733. + if ((rep>='a') && (rep<='z'))
  8734. + rep -= 0x20;
  8735. + }
  8736. + while ((rep!='Y') && (rep!='N') && (rep!='A'));
  8737. + }
  8738. +
  8739. + if (rep == 'N')
  8740. + skip = 1;
  8741. +
  8742. + if (rep == 'A')
  8743. + *popt_overwrite=1;
  8744. + }
  8745. +
  8746. + if ((skip==0) && (err==UNZ_OK))
  8747. + {
  8748. + fout=fopen64(write_filename,"wb");
  8749. +
  8750. + /* some zipfile don't contain directory alone before file */
  8751. + if ((fout==NULL) && ((*popt_extract_without_path)==0) &&
  8752. + (filename_withoutpath!=(char*)filename_inzip))
  8753. + {
  8754. + char c=*(filename_withoutpath-1);
  8755. + *(filename_withoutpath-1)='\0';
  8756. + makedir(write_filename);
  8757. + *(filename_withoutpath-1)=c;
  8758. + fout=fopen64(write_filename,"wb");
  8759. + }
  8760. +
  8761. + if (fout==NULL)
  8762. + {
  8763. + //printf("error opening %s\n",write_filename);
  8764. + }
  8765. + }
  8766. +
  8767. + if (fout!=NULL)
  8768. + {
  8769. + //printf(" extracting: %s\n",write_filename);
  8770. +
  8771. + do
  8772. + {
  8773. + err = unzReadCurrentFile(uf,buf,size_buf);
  8774. + if (err<0)
  8775. + {
  8776. + //printf("error %d with zipfile in unzReadCurrentFile\n",err);
  8777. + break;
  8778. + }
  8779. + if (err>0)
  8780. + if (fwrite(buf,err,1,fout)!=1)
  8781. + {
  8782. + //printf("error in writing extracted file\n");
  8783. + err=UNZ_ERRNO;
  8784. + break;
  8785. + }
  8786. + }
  8787. + while (err>0);
  8788. + if (fout)
  8789. + fclose(fout);
  8790. +
  8791. + if (err==0)
  8792. + change_file_date(write_filename,file_info.dosDate,
  8793. + file_info.tmu_date);
  8794. + }
  8795. +
  8796. + if (err==UNZ_OK)
  8797. + {
  8798. + err = unzCloseCurrentFile (uf);
  8799. + if (err!=UNZ_OK)
  8800. + {
  8801. + //printf("error %d with zipfile in unzCloseCurrentFile\n",err);
  8802. + }
  8803. + }
  8804. + else
  8805. + unzCloseCurrentFile(uf); /* don't lose the error */
  8806. + }
  8807. +
  8808. + free(buf);
  8809. + return err;
  8810. +}
  8811. +
  8812. +
  8813. +int do_extract(uf,opt_extract_without_path,opt_overwrite,password)
  8814. + unzFile uf;
  8815. + int opt_extract_without_path;
  8816. + int opt_overwrite;
  8817. + const char* password;
  8818. +{
  8819. + uLong i;
  8820. + unz_global_info64 gi;
  8821. + int err;
  8822. + FILE* fout=NULL;
  8823. +
  8824. + err = unzGetGlobalInfo64(uf,&gi);
  8825. + if (err!=UNZ_OK) {
  8826. + //printf("error %d with zipfile in unzGetGlobalInfo \n",err);
  8827. + }
  8828. +
  8829. + for (i=0;i<gi.number_entry;i++)
  8830. + {
  8831. + if (do_extract_currentfile(uf,&opt_extract_without_path,
  8832. + &opt_overwrite,
  8833. + password) != UNZ_OK)
  8834. + break;
  8835. +
  8836. + if ((i+1)<gi.number_entry)
  8837. + {
  8838. + err = unzGoToNextFile(uf);
  8839. + if (err!=UNZ_OK)
  8840. + {
  8841. + //printf("error %d with zipfile in unzGoToNextFile\n",err);
  8842. + break;
  8843. + }
  8844. + }
  8845. + }
  8846. +
  8847. + return 0;
  8848. +}
  8849. +
  8850. +int do_extract_onefile(uf,filename,opt_extract_without_path,opt_overwrite,password)
  8851. + unzFile uf;
  8852. + const char* filename;
  8853. + int opt_extract_without_path;
  8854. + int opt_overwrite;
  8855. + const char* password;
  8856. +{
  8857. + int err = UNZ_OK;
  8858. + if (unzLocateFile(uf,filename,CASESENSITIVITY)!=UNZ_OK)
  8859. + {
  8860. + //printf("file %s not found in the zipfile\n",filename);
  8861. + return 2;
  8862. + }
  8863. +
  8864. + if (do_extract_currentfile(uf,&opt_extract_without_path,
  8865. + &opt_overwrite,
  8866. + password) == UNZ_OK)
  8867. + return 0;
  8868. + else
  8869. + return 1;
  8870. +}
  8871. +
  8872. +#if WIN32
  8873. + #include <direct.h>
  8874. + #define GetCurrentDir _getcwd
  8875. +#else
  8876. + #include <unistd.h>
  8877. + #define GetCurrentDir getcwd
  8878. + #endif
  8879. +
  8880. +int my_miniunz(
  8881. + char ** savefile,
  8882. + const char * savefile2,
  8883. + const char * savedir) {
  8884. + const char *zipfilename=NULL;
  8885. + const char *filename_to_extract=NULL;
  8886. + const char *password=NULL;
  8887. + char filename_try[MAXFILENAME+16] = "";
  8888. + int i;
  8889. + int ret_value=0;
  8890. + int opt_do_extract=1;
  8891. + int opt_do_extract_withoutpath=0;
  8892. + int opt_overwrite=0;
  8893. + int opt_extractdir=0;
  8894. + const char *dirname=NULL;
  8895. + unzFile uf=NULL;
  8896. +
  8897. + opt_do_extract = opt_do_extract_withoutpath = 1;
  8898. + opt_overwrite=1;
  8899. + opt_extractdir=1;
  8900. + dirname=savedir;
  8901. + zipfilename = savefile;
  8902. + filename_to_extract = savefile2;
  8903. +
  8904. + if (zipfilename!=NULL)
  8905. + {
  8906. +
  8907. +# ifdef USEWIN32IOAPI
  8908. + zlib_filefunc64_def ffunc;
  8909. +# endif
  8910. +
  8911. + strncpy(filename_try, zipfilename,MAXFILENAME-1);
  8912. + /* strncpy doesnt append the trailing NULL, of the string is too long. */
  8913. + filename_try[ MAXFILENAME ] = '\0';
  8914. +
  8915. +# ifdef USEWIN32IOAPI
  8916. + fill_win32_filefunc64A(&ffunc);
  8917. + uf = unzOpen2_64(zipfilename,&ffunc);
  8918. +# else
  8919. + uf = unzOpen64(zipfilename);
  8920. +# endif
  8921. + }
  8922. +
  8923. + if (uf==NULL)
  8924. + {
  8925. + //printf("Cannot open %s\n",zipfilename,zipfilename);
  8926. + return 1;
  8927. + }
  8928. + //printf("%s opened\n",filename_try);
  8929. +
  8930. + if (opt_do_extract==1)
  8931. + {
  8932. + char cCurrentPath[FILENAME_MAX];
  8933. + GetCurrentDir(cCurrentPath, sizeof(cCurrentPath));
  8934. +#ifdef _WIN32
  8935. + _chdir(dirname);
  8936. +#else
  8937. + chdir(dirname);
  8938. +#endif
  8939. + ret_value = do_extract_onefile(uf, filename_to_extract, opt_do_extract_withoutpath, opt_overwrite, password);
  8940. + chdir(cCurrentPath);
  8941. + }
  8942. +
  8943. + unzClose(uf);
  8944. +
  8945. + return ret_value;
  8946. +}
  8947. Index: src/minizip.c
  8948. ===================================================================
  8949. --- src/minizip.c (nonexistent)
  8950. +++ src/minizip.c (working copy)
  8951. @@ -0,0 +1,377 @@
  8952. +/*
  8953. + minizip.c
  8954. + Version 1.1, February 14h, 2010
  8955. + sample part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
  8956. +
  8957. + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
  8958. +
  8959. + Modifications of Unzip for Zip64
  8960. + Copyright (C) 2007-2008 Even Rouault
  8961. +
  8962. + Modifications for Zip64 support on both zip and unzip
  8963. + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
  8964. +*/
  8965. +
  8966. +#ifndef _WIN32
  8967. + #ifndef __USE_FILE_OFFSET64
  8968. + #define __USE_FILE_OFFSET64
  8969. + #endif
  8970. + #ifndef __USE_LARGEFILE64
  8971. + #define __USE_LARGEFILE64
  8972. + #endif
  8973. + #ifndef _LARGEFILE64_SOURCE
  8974. + #define _LARGEFILE64_SOURCE
  8975. + #endif
  8976. + #ifndef _FILE_OFFSET_BIT
  8977. + #define _FILE_OFFSET_BIT 64
  8978. + #endif
  8979. +#endif
  8980. +
  8981. +#include <stdio.h>
  8982. +#include <stdlib.h>
  8983. +#include <string.h>
  8984. +#include <time.h>
  8985. +#include <errno.h>
  8986. +#include <fcntl.h>
  8987. +
  8988. +#ifdef unix
  8989. +# include <unistd.h>
  8990. +# include <utime.h>
  8991. +# include <sys/types.h>
  8992. +# include <sys/stat.h>
  8993. +#elif __APPLE__
  8994. +#else
  8995. +# include <direct.h>
  8996. +# include <io.h>
  8997. +#endif
  8998. +
  8999. +#include "zip.h"
  9000. +
  9001. +#ifdef _WIN32
  9002. + #define USEWIN32IOAPI
  9003. + #include "iowin32.h"
  9004. +#endif
  9005. +
  9006. +
  9007. +
  9008. +#define WRITEBUFFERSIZE (16384)
  9009. +#define MAXFILENAME (256)
  9010. +
  9011. +#ifdef _WIN32
  9012. +uLong filetime(f, tmzip, dt)
  9013. + char *f; /* name of file to get info on */
  9014. + tm_zip *tmzip; /* return value: access, modific. and creation times */
  9015. + uLong *dt; /* dostime */
  9016. +{
  9017. + int ret = 0;
  9018. + {
  9019. + FILETIME ftLocal;
  9020. + HANDLE hFind;
  9021. + WIN32_FIND_DATAA ff32;
  9022. +
  9023. + hFind = FindFirstFileA(f,&ff32);
  9024. + if (hFind != INVALID_HANDLE_VALUE)
  9025. + {
  9026. + FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal);
  9027. + FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0);
  9028. + FindClose(hFind);
  9029. + ret = 1;
  9030. + }
  9031. + }
  9032. + return ret;
  9033. +}
  9034. +#else
  9035. +#ifdef unix
  9036. +uLong filetime(f, tmzip, dt)
  9037. + char *f; /* name of file to get info on */
  9038. + tm_zip *tmzip; /* return value: access, modific. and creation times */
  9039. + uLong *dt; /* dostime */
  9040. +{
  9041. + int ret=0;
  9042. + struct stat s; /* results of stat() */
  9043. + struct tm* filedate;
  9044. + time_t tm_t=0;
  9045. +
  9046. + if (strcmp(f,"-")!=0)
  9047. + {
  9048. + char name[MAXFILENAME+1];
  9049. + int len = strlen(f);
  9050. + if (len > MAXFILENAME)
  9051. + len = MAXFILENAME;
  9052. +
  9053. + strncpy(name, f,MAXFILENAME-1);
  9054. + /* strncpy doesnt append the trailing NULL, of the string is too long. */
  9055. + name[ MAXFILENAME ] = '\0';
  9056. +
  9057. + if (name[len - 1] == '/')
  9058. + name[len - 1] = '\0';
  9059. + /* not all systems allow stat'ing a file with / appended */
  9060. + if (stat(name,&s)==0)
  9061. + {
  9062. + tm_t = s.st_mtime;
  9063. + ret = 1;
  9064. + }
  9065. + }
  9066. + filedate = localtime(&tm_t);
  9067. +
  9068. + tmzip->tm_sec = filedate->tm_sec;
  9069. + tmzip->tm_min = filedate->tm_min;
  9070. + tmzip->tm_hour = filedate->tm_hour;
  9071. + tmzip->tm_mday = filedate->tm_mday;
  9072. + tmzip->tm_mon = filedate->tm_mon ;
  9073. + tmzip->tm_year = filedate->tm_year;
  9074. +
  9075. + return ret;
  9076. +}
  9077. +#else
  9078. +uLong filetime(f, tmzip, dt)
  9079. + char *f; /* name of file to get info on */
  9080. + tm_zip *tmzip; /* return value: access, modific. and creation times */
  9081. + uLong *dt; /* dostime */
  9082. +{
  9083. + return 0;
  9084. +}
  9085. +#endif
  9086. +#endif
  9087. +
  9088. +
  9089. +
  9090. +
  9091. +int check_exist_file(filename)
  9092. + const char* filename;
  9093. +{
  9094. + FILE* ftestexist;
  9095. + int ret = 1;
  9096. + ftestexist = fopen64(filename,"rb");
  9097. + if (ftestexist==NULL)
  9098. + ret = 0;
  9099. + else
  9100. + fclose(ftestexist);
  9101. + return ret;
  9102. +}
  9103. +
  9104. +/* calculate the CRC32 of a file,
  9105. + because to encrypt a file, we need known the CRC32 of the file before */
  9106. +int getFileCrc(const char* filenameinzip,void*buf,unsigned long size_buf,unsigned long* result_crc)
  9107. +{
  9108. + unsigned long calculate_crc=0;
  9109. + int err=ZIP_OK;
  9110. + FILE * fin = fopen64(filenameinzip,"rb");
  9111. + unsigned long size_read = 0;
  9112. + unsigned long total_read = 0;
  9113. + if (fin==NULL)
  9114. + {
  9115. + err = ZIP_ERRNO;
  9116. + }
  9117. +
  9118. + if (err == ZIP_OK)
  9119. + do
  9120. + {
  9121. + err = ZIP_OK;
  9122. + size_read = (int)fread(buf,1,size_buf,fin);
  9123. + if (size_read < size_buf)
  9124. + if (feof(fin)==0)
  9125. + {
  9126. + //printf("error in reading %s\n",filenameinzip);
  9127. + err = ZIP_ERRNO;
  9128. + }
  9129. +
  9130. + if (size_read>0)
  9131. + calculate_crc = crc32(calculate_crc,buf,size_read);
  9132. + total_read += size_read;
  9133. +
  9134. + } while ((err == ZIP_OK) && (size_read>0));
  9135. +
  9136. + if (fin)
  9137. + fclose(fin);
  9138. +
  9139. + *result_crc=calculate_crc;
  9140. + //printf("file %s crc %lx\n", filenameinzip, calculate_crc);
  9141. + return err;
  9142. +}
  9143. +
  9144. +int isLargeFile(const char* filename)
  9145. +{
  9146. + int largeFile = 0;
  9147. + ZPOS64_T pos = 0;
  9148. + FILE* pFile = fopen64(filename, "rb");
  9149. +
  9150. + if(pFile != NULL)
  9151. + {
  9152. + int n = fseeko64(pFile, 0, SEEK_END);
  9153. +
  9154. + pos = ftello64(pFile);
  9155. +
  9156. + //printf("File : %s is %lld bytes\n", filename, pos);
  9157. +
  9158. + if(pos >= 0xffffffff)
  9159. + largeFile = 1;
  9160. +
  9161. + fclose(pFile);
  9162. + }
  9163. +
  9164. + return largeFile;
  9165. +}
  9166. +
  9167. +int my_minizip(
  9168. + char ** savefile,
  9169. + char ** savefile2) {
  9170. + int i;
  9171. + int opt_overwrite=0;
  9172. + int opt_compress_level=Z_DEFAULT_COMPRESSION;
  9173. + int opt_exclude_path=0;
  9174. + int zipfilenamearg = 0;
  9175. + //char filename_try[MAXFILENAME+16];
  9176. + int zipok;
  9177. + int err=0;
  9178. + int size_buf=0;
  9179. + void* buf=NULL;
  9180. + const char* password=NULL;
  9181. +
  9182. + opt_overwrite = 2;
  9183. + opt_compress_level = 9;
  9184. + opt_exclude_path = 1;
  9185. +
  9186. + size_buf = WRITEBUFFERSIZE;
  9187. + buf = (void*)malloc(size_buf);
  9188. + if (buf==NULL)
  9189. + {
  9190. + //printf("Error allocating memory\n");
  9191. + return ZIP_INTERNALERROR;
  9192. + }
  9193. +
  9194. + {
  9195. + zipFile zf;
  9196. + int errclose;
  9197. +# ifdef USEWIN32IOAPI
  9198. + zlib_filefunc64_def ffunc;
  9199. + fill_win32_filefunc64A(&ffunc);
  9200. + zf = zipOpen2_64(savefile,(opt_overwrite==2) ? 2 : 0,NULL,&ffunc);
  9201. +# else
  9202. + zf = zipOpen64(savefile,(opt_overwrite==2) ? 2 : 0);
  9203. +# endif
  9204. +
  9205. + if (zf == NULL)
  9206. + {
  9207. + //printf("error opening %s\n",savefile);
  9208. + err= ZIP_ERRNO;
  9209. + }
  9210. + else
  9211. + //printf("creating %s\n",savefile);
  9212. +
  9213. + {
  9214. + FILE * fin;
  9215. + int size_read;
  9216. + const char* filenameinzip = savefile2;
  9217. + const char *savefilenameinzip;
  9218. + zip_fileinfo zi;
  9219. + unsigned long crcFile=0;
  9220. + int zip64 = 0;
  9221. +
  9222. + zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour =
  9223. + zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0;
  9224. + zi.dosDate = 0;
  9225. + zi.internal_fa = 0;
  9226. + zi.external_fa = 0;
  9227. + filetime(filenameinzip,&zi.tmz_date,&zi.dosDate);
  9228. +
  9229. + if ((password != NULL) && (err==ZIP_OK))
  9230. + err = getFileCrc(filenameinzip,buf,size_buf,&crcFile);
  9231. +
  9232. + zip64 = isLargeFile(filenameinzip);
  9233. +
  9234. + /* The path name saved, should not include a leading slash. */
  9235. + /*if it did, windows/xp and dynazip couldn't read the zip file. */
  9236. + savefilenameinzip = filenameinzip;
  9237. + while( savefilenameinzip[0] == '\\' || savefilenameinzip[0] == '/' )
  9238. + {
  9239. + savefilenameinzip++;
  9240. + }
  9241. +
  9242. + /*should the zip file contain any path at all?*/
  9243. + if( opt_exclude_path )
  9244. + {
  9245. + const char *tmpptr;
  9246. + const char *lastslash = 0;
  9247. + for( tmpptr = savefilenameinzip; *tmpptr; tmpptr++)
  9248. + {
  9249. + if( *tmpptr == '\\' || *tmpptr == '/')
  9250. + {
  9251. + lastslash = tmpptr;
  9252. + }
  9253. + }
  9254. + if( lastslash != NULL )
  9255. + {
  9256. + savefilenameinzip = lastslash+1; // base filename follows last slash.
  9257. + }
  9258. + }
  9259. +
  9260. + /**/
  9261. + err = zipOpenNewFileInZip3_64(zf,savefilenameinzip,&zi,
  9262. + NULL,0,NULL,0,NULL /* comment*/,
  9263. + (opt_compress_level != 0) ? Z_DEFLATED : 0,
  9264. + opt_compress_level,0,
  9265. + /* -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, */
  9266. + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
  9267. + password,crcFile, zip64);
  9268. +
  9269. + if (err != ZIP_OK) {
  9270. + //printf("error in opening %s in zipfile\n",filenameinzip);
  9271. + }
  9272. + else
  9273. + {
  9274. + fin = fopen64(filenameinzip,"rb");
  9275. + if (fin==NULL)
  9276. + {
  9277. + err=ZIP_ERRNO;
  9278. + //printf("error in opening %s for reading\n",filenameinzip);
  9279. + }
  9280. + }
  9281. +
  9282. + if (err == ZIP_OK)
  9283. + do
  9284. + {
  9285. + err = ZIP_OK;
  9286. + size_read = (int)fread(buf,1,size_buf,fin);
  9287. + if (size_read < size_buf)
  9288. + if (feof(fin)==0)
  9289. + {
  9290. + //printf("error in reading %s\n",filenameinzip);
  9291. + err = ZIP_ERRNO;
  9292. + }
  9293. +
  9294. + if (size_read>0)
  9295. + {
  9296. + err = zipWriteInFileInZip (zf,buf,size_read);
  9297. + if (err<0)
  9298. + {
  9299. + //printf("error in writing %s in the zipfile\n",
  9300. + // filenameinzip);
  9301. + }
  9302. +
  9303. + }
  9304. + } while ((err == ZIP_OK) && (size_read>0));
  9305. +
  9306. + if (fin)
  9307. + fclose(fin);
  9308. +
  9309. + if (err<0)
  9310. + err=ZIP_ERRNO;
  9311. + else
  9312. + {
  9313. + err = zipCloseFileInZip(zf);
  9314. + if (err!=ZIP_OK) {
  9315. + //printf("error in closing %s in the zipfile\n",
  9316. + // filenameinzip);
  9317. + }
  9318. + }
  9319. + }
  9320. + errclose = zipClose(zf,NULL);
  9321. + if (errclose != ZIP_OK) {
  9322. + //printf("error in closing %s\n",savefile);
  9323. + }
  9324. + }
  9325. +
  9326. + free(buf);
  9327. + return 0;
  9328. +}
  9329. Index: src/mztools.c
  9330. ===================================================================
  9331. --- src/mztools.c (nonexistent)
  9332. +++ src/mztools.c (working copy)
  9333. @@ -0,0 +1,281 @@
  9334. +/*
  9335. + Additional tools for Minizip
  9336. + Code: Xavier Roche '2004
  9337. + License: Same as ZLIB (www.gzip.org)
  9338. +*/
  9339. +
  9340. +/* Code */
  9341. +#include <stdio.h>
  9342. +#include <stdlib.h>
  9343. +#include <string.h>
  9344. +#include "zlib.h"
  9345. +#include "unzip.h"
  9346. +
  9347. +#define READ_8(adr) ((unsigned char)*(adr))
  9348. +#define READ_16(adr) ( READ_8(adr) | (READ_8(adr+1) << 8) )
  9349. +#define READ_32(adr) ( READ_16(adr) | (READ_16((adr)+2) << 16) )
  9350. +
  9351. +#define WRITE_8(buff, n) do { \
  9352. + *((unsigned char*)(buff)) = (unsigned char) ((n) & 0xff); \
  9353. +} while(0)
  9354. +#define WRITE_16(buff, n) do { \
  9355. + WRITE_8((unsigned char*)(buff), n); \
  9356. + WRITE_8(((unsigned char*)(buff)) + 1, (n) >> 8); \
  9357. +} while(0)
  9358. +#define WRITE_32(buff, n) do { \
  9359. + WRITE_16((unsigned char*)(buff), (n) & 0xffff); \
  9360. + WRITE_16((unsigned char*)(buff) + 2, (n) >> 16); \
  9361. +} while(0)
  9362. +
  9363. +extern int ZEXPORT unzRepair(file, fileOut, fileOutTmp, nRecovered, bytesRecovered)
  9364. +const char* file;
  9365. +const char* fileOut;
  9366. +const char* fileOutTmp;
  9367. +uLong* nRecovered;
  9368. +uLong* bytesRecovered;
  9369. +{
  9370. + int err = Z_OK;
  9371. + FILE* fpZip = fopen(file, "rb");
  9372. + FILE* fpOut = fopen(fileOut, "wb");
  9373. + FILE* fpOutCD = fopen(fileOutTmp, "wb");
  9374. + if (fpZip != NULL && fpOut != NULL) {
  9375. + int entries = 0;
  9376. + uLong totalBytes = 0;
  9377. + char header[30];
  9378. + char filename[256];
  9379. + char extra[1024];
  9380. + int offset = 0;
  9381. + int offsetCD = 0;
  9382. + while ( fread(header, 1, 30, fpZip) == 30 ) {
  9383. + int currentOffset = offset;
  9384. +
  9385. + /* File entry */
  9386. + if (READ_32(header) == 0x04034b50) {
  9387. + unsigned int version = READ_16(header + 4);
  9388. + unsigned int gpflag = READ_16(header + 6);
  9389. + unsigned int method = READ_16(header + 8);
  9390. + unsigned int filetime = READ_16(header + 10);
  9391. + unsigned int filedate = READ_16(header + 12);
  9392. + unsigned int crc = READ_32(header + 14); /* crc */
  9393. + unsigned int cpsize = READ_32(header + 18); /* compressed size */
  9394. + unsigned int uncpsize = READ_32(header + 22); /* uncompressed sz */
  9395. + unsigned int fnsize = READ_16(header + 26); /* file name length */
  9396. + unsigned int extsize = READ_16(header + 28); /* extra field length */
  9397. + filename[0] = extra[0] = '\0';
  9398. +
  9399. + /* Header */
  9400. + if (fwrite(header, 1, 30, fpOut) == 30) {
  9401. + offset += 30;
  9402. + } else {
  9403. + err = Z_ERRNO;
  9404. + break;
  9405. + }
  9406. +
  9407. + /* Filename */
  9408. + if (fnsize > 0) {
  9409. + if (fread(filename, 1, fnsize, fpZip) == fnsize) {
  9410. + if (fwrite(filename, 1, fnsize, fpOut) == fnsize) {
  9411. + offset += fnsize;
  9412. + } else {
  9413. + err = Z_ERRNO;
  9414. + break;
  9415. + }
  9416. + } else {
  9417. + err = Z_ERRNO;
  9418. + break;
  9419. + }
  9420. + } else {
  9421. + err = Z_STREAM_ERROR;
  9422. + break;
  9423. + }
  9424. +
  9425. + /* Extra field */
  9426. + if (extsize > 0) {
  9427. + if (fread(extra, 1, extsize, fpZip) == extsize) {
  9428. + if (fwrite(extra, 1, extsize, fpOut) == extsize) {
  9429. + offset += extsize;
  9430. + } else {
  9431. + err = Z_ERRNO;
  9432. + break;
  9433. + }
  9434. + } else {
  9435. + err = Z_ERRNO;
  9436. + break;
  9437. + }
  9438. + }
  9439. +
  9440. + /* Data */
  9441. + {
  9442. + int dataSize = cpsize;
  9443. + if (dataSize == 0) {
  9444. + dataSize = uncpsize;
  9445. + }
  9446. + if (dataSize > 0) {
  9447. + char* data = malloc(dataSize);
  9448. + if (data != NULL) {
  9449. + if ((int)fread(data, 1, dataSize, fpZip) == dataSize) {
  9450. + if ((int)fwrite(data, 1, dataSize, fpOut) == dataSize) {
  9451. + offset += dataSize;
  9452. + totalBytes += dataSize;
  9453. + } else {
  9454. + err = Z_ERRNO;
  9455. + }
  9456. + } else {
  9457. + err = Z_ERRNO;
  9458. + }
  9459. + free(data);
  9460. + if (err != Z_OK) {
  9461. + break;
  9462. + }
  9463. + } else {
  9464. + err = Z_MEM_ERROR;
  9465. + break;
  9466. + }
  9467. + }
  9468. + }
  9469. +
  9470. + /* Central directory entry */
  9471. + {
  9472. + char header[46];
  9473. + char* comment = "";
  9474. + int comsize = (int) strlen(comment);
  9475. + WRITE_32(header, 0x02014b50);
  9476. + WRITE_16(header + 4, version);
  9477. + WRITE_16(header + 6, version);
  9478. + WRITE_16(header + 8, gpflag);
  9479. + WRITE_16(header + 10, method);
  9480. + WRITE_16(header + 12, filetime);
  9481. + WRITE_16(header + 14, filedate);
  9482. + WRITE_32(header + 16, crc);
  9483. + WRITE_32(header + 20, cpsize);
  9484. + WRITE_32(header + 24, uncpsize);
  9485. + WRITE_16(header + 28, fnsize);
  9486. + WRITE_16(header + 30, extsize);
  9487. + WRITE_16(header + 32, comsize);
  9488. + WRITE_16(header + 34, 0); /* disk # */
  9489. + WRITE_16(header + 36, 0); /* int attrb */
  9490. + WRITE_32(header + 38, 0); /* ext attrb */
  9491. + WRITE_32(header + 42, currentOffset);
  9492. + /* Header */
  9493. + if (fwrite(header, 1, 46, fpOutCD) == 46) {
  9494. + offsetCD += 46;
  9495. +
  9496. + /* Filename */
  9497. + if (fnsize > 0) {
  9498. + if (fwrite(filename, 1, fnsize, fpOutCD) == fnsize) {
  9499. + offsetCD += fnsize;
  9500. + } else {
  9501. + err = Z_ERRNO;
  9502. + break;
  9503. + }
  9504. + } else {
  9505. + err = Z_STREAM_ERROR;
  9506. + break;
  9507. + }
  9508. +
  9509. + /* Extra field */
  9510. + if (extsize > 0) {
  9511. + if (fwrite(extra, 1, extsize, fpOutCD) == extsize) {
  9512. + offsetCD += extsize;
  9513. + } else {
  9514. + err = Z_ERRNO;
  9515. + break;
  9516. + }
  9517. + }
  9518. +
  9519. + /* Comment field */
  9520. + if (comsize > 0) {
  9521. + if ((int)fwrite(comment, 1, comsize, fpOutCD) == comsize) {
  9522. + offsetCD += comsize;
  9523. + } else {
  9524. + err = Z_ERRNO;
  9525. + break;
  9526. + }
  9527. + }
  9528. +
  9529. +
  9530. + } else {
  9531. + err = Z_ERRNO;
  9532. + break;
  9533. + }
  9534. + }
  9535. +
  9536. + /* Success */
  9537. + entries++;
  9538. +
  9539. + } else {
  9540. + break;
  9541. + }
  9542. + }
  9543. +
  9544. + /* Final central directory */
  9545. + {
  9546. + int entriesZip = entries;
  9547. + char header[22];
  9548. + char* comment = ""; // "ZIP File recovered by zlib/minizip/mztools";
  9549. + int comsize = (int) strlen(comment);
  9550. + if (entriesZip > 0xffff) {
  9551. + entriesZip = 0xffff;
  9552. + }
  9553. + WRITE_32(header, 0x06054b50);
  9554. + WRITE_16(header + 4, 0); /* disk # */
  9555. + WRITE_16(header + 6, 0); /* disk # */
  9556. + WRITE_16(header + 8, entriesZip); /* hack */
  9557. + WRITE_16(header + 10, entriesZip); /* hack */
  9558. + WRITE_32(header + 12, offsetCD); /* size of CD */
  9559. + WRITE_32(header + 16, offset); /* offset to CD */
  9560. + WRITE_16(header + 20, comsize); /* comment */
  9561. +
  9562. + /* Header */
  9563. + if (fwrite(header, 1, 22, fpOutCD) == 22) {
  9564. +
  9565. + /* Comment field */
  9566. + if (comsize > 0) {
  9567. + if ((int)fwrite(comment, 1, comsize, fpOutCD) != comsize) {
  9568. + err = Z_ERRNO;
  9569. + }
  9570. + }
  9571. +
  9572. + } else {
  9573. + err = Z_ERRNO;
  9574. + }
  9575. + }
  9576. +
  9577. + /* Final merge (file + central directory) */
  9578. + fclose(fpOutCD);
  9579. + if (err == Z_OK) {
  9580. + fpOutCD = fopen(fileOutTmp, "rb");
  9581. + if (fpOutCD != NULL) {
  9582. + int nRead;
  9583. + char buffer[8192];
  9584. + while ( (nRead = (int)fread(buffer, 1, sizeof(buffer), fpOutCD)) > 0) {
  9585. + if ((int)fwrite(buffer, 1, nRead, fpOut) != nRead) {
  9586. + err = Z_ERRNO;
  9587. + break;
  9588. + }
  9589. + }
  9590. + fclose(fpOutCD);
  9591. + }
  9592. + }
  9593. +
  9594. + /* Close */
  9595. + fclose(fpZip);
  9596. + fclose(fpOut);
  9597. +
  9598. + /* Wipe temporary file */
  9599. + (void)remove(fileOutTmp);
  9600. +
  9601. + /* Number of recovered entries */
  9602. + if (err == Z_OK) {
  9603. + if (nRecovered != NULL) {
  9604. + *nRecovered = entries;
  9605. + }
  9606. + if (bytesRecovered != NULL) {
  9607. + *bytesRecovered = totalBytes;
  9608. + }
  9609. + }
  9610. + } else {
  9611. + err = Z_STREAM_ERROR;
  9612. + }
  9613. + return err;
  9614. +}
  9615. Index: src/save_state.cpp
  9616. ===================================================================
  9617. --- src/save_state.cpp (nonexistent)
  9618. +++ src/save_state.cpp (working copy)
  9619. @@ -0,0 +1,394 @@
  9620. +#include "save_state.h"
  9621. +#include "zlib.h"
  9622. +#ifdef WIN32
  9623. +#include "direct.h"
  9624. +#endif
  9625. +#include "cross.h"
  9626. +#include "logging.h"
  9627. +#if defined (__APPLE__)
  9628. +#else
  9629. +#include <malloc.h>
  9630. +#endif
  9631. +#include <cstring>
  9632. +#include <fstream>
  9633. +
  9634. +#include <stdio.h>
  9635. +#include <sys/stat.h>
  9636. +#include <sys/types.h>
  9637. +#include <string>
  9638. +#include <stdlib.h>
  9639. +#include "SDL.h"
  9640. +
  9641. +#ifndef WIN32
  9642. +char* itoa(int value, char* str, int radix) {
  9643. + /**
  9644. + * C++ version 0.4 char* style "itoa":
  9645. + * Written by Lukás Chmela
  9646. + * Released under GPLv3.
  9647. + */
  9648. + // check that the radix if valid
  9649. + if (radix < 2 || radix > 36) { *str = '\0'; return str; }
  9650. +
  9651. + char* ptr = str, *ptr1 = str, tmp_char;
  9652. + int tmp_value;
  9653. +
  9654. + do {
  9655. + tmp_value = value;
  9656. + value /= radix;
  9657. + *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * radix)];
  9658. + } while ( value );
  9659. +
  9660. + // Apply negative sign
  9661. + if (tmp_value < 0) *ptr++ = '-';
  9662. + *ptr-- = '\0';
  9663. + while(ptr1 < ptr) {
  9664. + tmp_char = *ptr;
  9665. + *ptr--= *ptr1;
  9666. + *ptr1++ = tmp_char;
  9667. + }
  9668. + return str;
  9669. +}
  9670. +#endif
  9671. +
  9672. +SaveState& SaveState::instance() {
  9673. + static SaveState singleton;
  9674. + return singleton;
  9675. +}
  9676. +
  9677. +void SaveState::registerComponent(const std::string& uniqueName, Component& comp) {
  9678. + components.insert(std::make_pair(uniqueName, CompData(comp)));
  9679. +}
  9680. +
  9681. +namespace Util {
  9682. +std::string compress(const std::string& input) { //throw (SaveState::Error)
  9683. + if (input.empty())
  9684. + return input;
  9685. +
  9686. + const uLong bufferSize = ::compressBound(input.size());
  9687. +
  9688. + std::string output;
  9689. + output.resize(bufferSize);
  9690. +
  9691. + uLongf actualSize = bufferSize;
  9692. + if (::compress2(reinterpret_cast<Bytef*>(&output[0]), &actualSize,
  9693. + reinterpret_cast<const Bytef*>(input.c_str()), input.size(), Z_BEST_SPEED) != Z_OK)
  9694. + throw SaveState::Error("Compression failed!");
  9695. +
  9696. + output.resize(actualSize);
  9697. +
  9698. + //save size of uncompressed data
  9699. + const size_t uncompressedSize = input.size(); //save size of uncompressed data
  9700. + output.resize(output.size() + sizeof(uncompressedSize)); //won't trigger a reallocation
  9701. + ::memcpy(&output[0] + output.size() - sizeof(uncompressedSize), &uncompressedSize, sizeof(uncompressedSize));
  9702. +
  9703. + return std::string(&output[0], output.size()); //strip reserved space
  9704. +}
  9705. +
  9706. +std::string decompress(const std::string& input) { //throw (SaveState::Error)
  9707. + if (input.empty())
  9708. + return input;
  9709. +
  9710. + //retrieve size of uncompressed data
  9711. + size_t uncompressedSize = 0;
  9712. + ::memcpy(&uncompressedSize, &input[0] + input.size() - sizeof(uncompressedSize), sizeof(uncompressedSize));
  9713. +
  9714. + std::string output;
  9715. + output.resize(uncompressedSize);
  9716. +
  9717. + uLongf actualSize = uncompressedSize;
  9718. + if (::uncompress(reinterpret_cast<Bytef*>(&output[0]), &actualSize,
  9719. + reinterpret_cast<const Bytef*>(input.c_str()), input.size() - sizeof(uncompressedSize)) != Z_OK)
  9720. + throw SaveState::Error("Decompression failed!");
  9721. +
  9722. + output.resize(actualSize); //should be superfluous!
  9723. +
  9724. + return output;
  9725. +}
  9726. +}
  9727. +
  9728. +inline void SaveState::RawBytes::set(const std::string& stream) {
  9729. + bytes = stream;
  9730. + isCompressed = false;
  9731. + dataExists = true;
  9732. +}
  9733. +
  9734. +inline std::string SaveState::RawBytes::get() const { //throw (Error){
  9735. + if (isCompressed)
  9736. + (Util::decompress(bytes)).swap(bytes);
  9737. + isCompressed = false;
  9738. + return bytes;
  9739. +}
  9740. +
  9741. +inline void SaveState::RawBytes::compress() const { //throw (Error)
  9742. + if (!isCompressed)
  9743. + (Util::compress(bytes)).swap(bytes);
  9744. + isCompressed = true;
  9745. +}
  9746. +
  9747. +inline bool SaveState::RawBytes::dataAvailable() const {
  9748. + return dataExists;
  9749. +}
  9750. +
  9751. +extern "C" {
  9752. + int my_minizip(char ** savefile,char ** savefile2);
  9753. + int my_miniunz(char ** savefile, const char * savefile2, const char * savedir);
  9754. +}
  9755. +
  9756. +void SaveState::save(size_t slot) { //throw (Error)
  9757. + if (slot >= SLOT_COUNT) return;
  9758. + SDL_PauseAudio(0);
  9759. + bool save_err=false;
  9760. + extern unsigned int MEM_TotalPages(void);
  9761. + if((MEM_TotalPages()*4096/1024/1024)>200) {
  9762. + LOG_MSG("Stopped. 200 MB is the maximum memory size for saving/loading states.");
  9763. + return;
  9764. + }
  9765. + bool create_title=false;
  9766. + bool create_memorysize=false;
  9767. + extern const char* RunningProgram;
  9768. + std::string path;
  9769. + bool Get_Custom_SaveDir(std::string& savedir);
  9770. + if(Get_Custom_SaveDir(path)) {
  9771. + path+=CROSS_FILESPLIT;
  9772. + } else {
  9773. + extern std::string capturedir;
  9774. + const size_t last_slash_idx = capturedir.find_last_of("\\/");
  9775. + if (std::string::npos != last_slash_idx) {
  9776. + path = capturedir.substr(0, last_slash_idx);
  9777. + } else {
  9778. + path = ".";
  9779. + }
  9780. + path+=CROSS_FILESPLIT;
  9781. + path+="save";
  9782. + Cross::CreateDir(path);
  9783. + path+=CROSS_FILESPLIT;
  9784. + }
  9785. +
  9786. + std::string temp, save2;
  9787. + std::stringstream slotname;
  9788. + slotname << slot+1;
  9789. + temp=path;
  9790. + std::string save=temp+slotname.str()+".sav";
  9791. + remove(save.c_str());
  9792. + std::ofstream file (save.c_str());
  9793. + file << "";
  9794. + file.close();
  9795. + try {
  9796. + for (CompEntry::iterator i = components.begin(); i != components.end(); ++i) {
  9797. + std::ostringstream ss;
  9798. + i->second.comp.getBytes(ss);
  9799. + i->second.rawBytes[slot].set(ss.str());
  9800. +
  9801. + //LOG_MSG("Component is %s",i->first.c_str());
  9802. +
  9803. + if(!create_title) {
  9804. + std::string tempname = temp+"Program_Name";
  9805. + std::ofstream programname (tempname.c_str(), std::ofstream::binary);
  9806. + programname << RunningProgram;
  9807. + create_title=true;
  9808. + programname.close();
  9809. + }
  9810. +
  9811. + if(!create_memorysize) {
  9812. + std::string tempname = temp+"Memory_Size";
  9813. + std::ofstream memorysize (tempname.c_str(), std::ofstream::binary);
  9814. + memorysize << MEM_TotalPages();
  9815. + create_memorysize=true;
  9816. + memorysize.close();
  9817. + }
  9818. + std::string realtemp;
  9819. + realtemp = temp + i->first;
  9820. + std::ofstream outfile (realtemp.c_str(), std::ofstream::binary);
  9821. + outfile << (Util::compress(ss.str()));
  9822. + //compress all other saved states except position "slot"
  9823. + //const std::vector<RawBytes>& rb = i->second.rawBytes;
  9824. + //std::for_each(rb.begin(), rb.begin() + slot, std::mem_fun_ref(&RawBytes::compress));
  9825. + //std::for_each(rb.begin() + slot + 1, rb.end(), std::mem_fun_ref(&RawBytes::compress));
  9826. + outfile.close();
  9827. + ss.clear();
  9828. + if(outfile.fail()) {
  9829. + LOG_MSG("Save failed! - %s", realtemp.c_str());
  9830. + save_err=true;
  9831. + remove(save.c_str());
  9832. + goto delete_all;
  9833. + }
  9834. + }
  9835. + }
  9836. + catch (const std::bad_alloc&) {
  9837. + LOG_MSG("Save failed! Out of Memory!");
  9838. + save_err=true;
  9839. + remove(save.c_str());
  9840. + goto delete_all;
  9841. + }
  9842. +
  9843. + for (CompEntry::iterator i = components.begin(); i != components.end(); ++i) {
  9844. + save2=temp+i->first;
  9845. + my_minizip((char **)save.c_str(), (char **)save2.c_str());
  9846. + }
  9847. + save2=temp+"Program_Name";
  9848. + my_minizip((char **)save.c_str(), (char **)save2.c_str());
  9849. + save2=temp+"Memory_Size";
  9850. + my_minizip((char **)save.c_str(), (char **)save2.c_str());
  9851. +
  9852. +delete_all:
  9853. + for (CompEntry::iterator i = components.begin(); i != components.end(); ++i) {
  9854. + save2=temp+i->first;
  9855. + remove(save2.c_str());
  9856. + }
  9857. + save2=temp+"Program_Name";
  9858. + remove(save2.c_str());
  9859. + save2=temp+"Memory_Size";
  9860. + remove(save2.c_str());
  9861. + if (!save_err) LOG_MSG("Saved. (Slot %d)",slot+1);
  9862. +}
  9863. +
  9864. +void SaveState::load(size_t slot) const { //throw (Error)
  9865. +// if (isEmpty(slot)) return;
  9866. + extern unsigned int MEM_TotalPages(void);
  9867. + bool load_err=false;
  9868. + if((MEM_TotalPages()*4096/1024/1024)>200) {
  9869. + LOG_MSG("Stopped. 200 MB is the maximum memory size for saving/loading states.");
  9870. + return;
  9871. + }
  9872. + SDL_PauseAudio(0);
  9873. + extern const char* RunningProgram;
  9874. + bool read_title=false;
  9875. + bool read_memorysize=false;
  9876. + std::string path;
  9877. + bool Get_Custom_SaveDir(std::string& savedir);
  9878. + if(Get_Custom_SaveDir(path)) {
  9879. + path+=CROSS_FILESPLIT;
  9880. + } else {
  9881. + extern std::string capturedir;
  9882. + const size_t last_slash_idx = capturedir.find_last_of("\\/");
  9883. + if (std::string::npos != last_slash_idx) {
  9884. + path = capturedir.substr(0, last_slash_idx);
  9885. + } else {
  9886. + path = ".";
  9887. + }
  9888. + path += CROSS_FILESPLIT;
  9889. + path +="save";
  9890. + path += CROSS_FILESPLIT;
  9891. + }
  9892. + std::string temp;
  9893. + temp = path;
  9894. + std::stringstream slotname;
  9895. + slotname << slot+1;
  9896. + std::string save=temp+slotname.str()+".sav";
  9897. + std::ifstream check_slot;
  9898. + check_slot.open(save.c_str(), std::ifstream::in);
  9899. + if(check_slot.fail()) {
  9900. + LOG_MSG("No saved slot - %d (%s)",slot+1,save.c_str());
  9901. + load_err=true;
  9902. + return;
  9903. + }
  9904. +
  9905. + for (CompEntry::const_iterator i = components.begin(); i != components.end(); ++i) {
  9906. + std::filebuf * fb;
  9907. + std::ifstream ss;
  9908. + std::ifstream check_file;
  9909. + fb = ss.rdbuf();
  9910. +
  9911. + //LOG_MSG("Component is %s",i->first.c_str());
  9912. +
  9913. + my_miniunz((char **)save.c_str(),i->first.c_str(),temp.c_str());
  9914. +
  9915. + if(!read_title) {
  9916. + my_miniunz((char **)save.c_str(),"Program_Name",temp.c_str());
  9917. + std::ifstream check_title;
  9918. + int length = 8;
  9919. +
  9920. + std::string tempname = temp+"Program_Name";
  9921. + check_title.open(tempname.c_str(), std::ifstream::in);
  9922. + if(check_title.fail()) {
  9923. + LOG_MSG("Save state corrupted! Program in inconsistent state! - Program_Name");
  9924. + load_err=true;
  9925. + goto delete_all;
  9926. + }
  9927. + check_title.seekg (0, std::ios::end);
  9928. + length = check_title.tellg();
  9929. + check_title.seekg (0, std::ios::beg);
  9930. +
  9931. + char * const buffer = (char*)alloca( (length+1) * sizeof(char)); // char buffer[length];
  9932. + check_title.read (buffer, length);
  9933. + check_title.close();
  9934. + if(strncmp(buffer,RunningProgram,length)) {
  9935. + buffer[length]='\0';
  9936. + LOG_MSG("Aborted. Check your program name: %s",buffer);
  9937. + load_err=true;
  9938. + goto delete_all;
  9939. + }
  9940. + read_title=true;
  9941. + }
  9942. +
  9943. + if(!read_memorysize) {
  9944. + my_miniunz((char **)save.c_str(),"Memory_Size",temp.c_str());
  9945. + std::fstream check_memorysize;
  9946. + int length = 8;
  9947. +
  9948. + std::string tempname = temp+"Memory_Size";
  9949. + check_memorysize.open(tempname.c_str(), std::ifstream::in);
  9950. + if(check_memorysize.fail()) {
  9951. + LOG_MSG("Save state corrupted! Program in inconsistent state! - Memory_Size");
  9952. + load_err=true;
  9953. + goto delete_all;
  9954. + }
  9955. + check_memorysize.seekg (0, std::ios::end);
  9956. + length = check_memorysize.tellg();
  9957. + check_memorysize.seekg (0, std::ios::beg);
  9958. +
  9959. + char * const buffer = (char*)alloca( (length+1) * sizeof(char)); // char buffer[length];
  9960. + check_memorysize.read (buffer, length);
  9961. + check_memorysize.close();
  9962. + char str[10];
  9963. + itoa(MEM_TotalPages(), str, 10);
  9964. + if(strncmp(buffer,str,length)) {
  9965. + buffer[length]='\0';
  9966. + LOG_MSG("WARNING: Check your memory size.");
  9967. + }
  9968. + read_memorysize=true;
  9969. + }
  9970. + std::string realtemp;
  9971. + realtemp = temp + i->first;
  9972. + check_file.open(realtemp.c_str(), std::ifstream::in);
  9973. + check_file.close();
  9974. + if(check_file.fail()) {
  9975. + LOG_MSG("Save state corrupted! Program in inconsistent state! - %s",i->first.c_str());
  9976. + load_err=true;
  9977. + goto delete_all;
  9978. + }
  9979. +
  9980. + fb->open(realtemp.c_str(),std::ios::in | std::ios::binary);
  9981. + std::string str((std::istreambuf_iterator<char>(ss)), std::istreambuf_iterator<char>());
  9982. + std::stringstream mystream;
  9983. + mystream << (Util::decompress(str));
  9984. + i->second.comp.setBytes(mystream);
  9985. + if (mystream.rdbuf()->in_avail() != 0 || mystream.eof()) { //basic consistency check
  9986. + LOG_MSG("Save state corrupted! Program in inconsistent state! - %s",i->first.c_str());
  9987. + load_err=true;
  9988. + goto delete_all;
  9989. + }
  9990. + //compress all other saved states except position "slot"
  9991. + //const std::vector<RawBytes>& rb = i->second.rawBytes;
  9992. + //std::for_each(rb.begin(), rb.begin() + slot, std::mem_fun_ref(&RawBytes::compress));
  9993. + //std::for_each(rb.begin() + slot + 1, rb.end(), std::mem_fun_ref(&RawBytes::compress));
  9994. + fb->close();
  9995. + mystream.clear();
  9996. + }
  9997. +delete_all:
  9998. + std::string save2;
  9999. + for (CompEntry::const_iterator i = components.begin(); i != components.end(); ++i) {
  10000. + save2=temp+i->first;
  10001. + remove(save2.c_str());
  10002. + }
  10003. + save2=temp+"Program_Name";
  10004. + remove(save2.c_str());
  10005. + save2=temp+"Memory_Size";
  10006. + remove(save2.c_str());
  10007. + if (!load_err) LOG_MSG("Loaded. (Slot %d)",slot+1);
  10008. +}
  10009. +
  10010. +bool SaveState::isEmpty(size_t slot) const {
  10011. + if (slot >= SLOT_COUNT) return true;
  10012. + return (components.empty() || !components.begin()->second.rawBytes[slot].dataAvailable());
  10013. +}
  10014. Index: src/save_state.h
  10015. ===================================================================
  10016. --- src/save_state.h (nonexistent)
  10017. +++ src/save_state.h (working copy)
  10018. @@ -0,0 +1,177 @@
  10019. +#ifndef SAVE_STATE_H_INCLUDED
  10020. +#define SAVE_STATE_H_INCLUDED
  10021. +
  10022. +#include <sstream>
  10023. +#include <map>
  10024. +#include <algorithm>
  10025. +#include <functional>
  10026. +#include <vector>
  10027. +
  10028. +
  10029. +#define WRITE_POD(x,y) \
  10030. + stream.write(reinterpret_cast<const char*>( (x) ), sizeof( (y) ) );
  10031. +
  10032. +#define WRITE_POD_SIZE(x,y) \
  10033. + stream.write(reinterpret_cast<const char*>( (x) ), (y) );
  10034. +
  10035. +#define READ_POD(x,y) \
  10036. + stream.read(reinterpret_cast<char*>( (x) ), sizeof( (y) ) );
  10037. +
  10038. +#define READ_POD_SIZE(x,y) \
  10039. + stream.read(reinterpret_cast<char*>( (x) ), (y) );
  10040. +
  10041. +
  10042. +
  10043. +class SaveState
  10044. +{
  10045. +public:
  10046. + static SaveState& instance();
  10047. +
  10048. + typedef std::string Error;
  10049. + static const size_t SLOT_COUNT = 10; //slot: [0,...,SLOT_COUNT - 1]
  10050. +
  10051. + void save (size_t slot); //throw (Error)
  10052. + void load (size_t slot) const; //throw (Error)
  10053. + bool isEmpty(size_t slot) const;
  10054. +
  10055. + //initialization: register relevant components on program startup
  10056. + struct Component
  10057. + {
  10058. + virtual void getBytes(std::ostream& stream) = 0;
  10059. + virtual void setBytes(std::istream& stream) = 0;
  10060. + };
  10061. +
  10062. + void registerComponent(const std::string& uniqueName, Component& comp); //comp must have global lifetime!
  10063. +
  10064. +private:
  10065. + SaveState() {}
  10066. + SaveState(const SaveState&);
  10067. + SaveState& operator=(const SaveState&);
  10068. +
  10069. + class RawBytes
  10070. + {
  10071. + public:
  10072. + RawBytes() : dataExists(false), isCompressed(false) {}
  10073. + void set(const std::string& stream);
  10074. + std::string get() const; //throw (Error)
  10075. + void compress() const; //throw (Error)
  10076. + bool dataAvailable() const;
  10077. + private:
  10078. + bool dataExists; //determine whether set method (even with empty string) was called
  10079. + mutable bool isCompressed; //design for logical not binary const
  10080. + mutable std::string bytes; //
  10081. + };
  10082. +
  10083. + struct CompData
  10084. + {
  10085. + CompData(Component& cmp) : comp(cmp), rawBytes(SLOT_COUNT) {}
  10086. + Component& comp;
  10087. + std::vector<RawBytes> rawBytes;
  10088. + };
  10089. +
  10090. + typedef std::map<std::string, CompData> CompEntry;
  10091. + CompEntry components;
  10092. +};
  10093. +
  10094. +
  10095. +//some helper functions
  10096. +template <class T>
  10097. +void writePOD(std::ostream& stream, const T& data);
  10098. +
  10099. +template <class T>
  10100. +void readPOD(std::istream& stream, T& data);
  10101. +
  10102. +void writeString(std::ostream& stream, const std::string& data);
  10103. +void readString(std::istream& stream, std::string& data);
  10104. +
  10105. +
  10106. +//Implementation of SaveState::Component for saving POD types only
  10107. +class SerializeGlobalPOD : public SaveState::Component
  10108. +{
  10109. +public:
  10110. + SerializeGlobalPOD(const std::string& compName)
  10111. + {
  10112. + SaveState::instance().registerComponent(compName, *this);
  10113. + }
  10114. +
  10115. + template <class T>
  10116. + void registerPOD(T& pod) //register POD for serializatioin
  10117. + {
  10118. + podRef.push_back(POD(pod));
  10119. + }
  10120. +
  10121. +protected:
  10122. + virtual void getBytes(std::ostream& stream)
  10123. + {
  10124. + std::for_each(podRef.begin(), podRef.end(), std::bind1st(WriteGlobalPOD(), &stream));
  10125. + }
  10126. +
  10127. + virtual void setBytes(std::istream& stream)
  10128. + {
  10129. + std::for_each(podRef.begin(), podRef.end(), std::bind1st(ReadGlobalPOD(), &stream));
  10130. + }
  10131. +
  10132. +private:
  10133. + struct POD
  10134. + {
  10135. + template <class T>
  10136. + POD(T& pod) : address(&pod), size(sizeof(T)) {}
  10137. + void* address;
  10138. + size_t size;
  10139. + };
  10140. +
  10141. + struct WriteGlobalPOD : public std::binary_function<std::ostream*, POD, void>
  10142. + {
  10143. + void operator()(std::ostream* stream, const POD& data) const
  10144. + {
  10145. + stream->write(static_cast<const char*>(data.address), data.size);
  10146. + }
  10147. + };
  10148. +
  10149. + struct ReadGlobalPOD : public std::binary_function<std::istream*, POD, void>
  10150. + {
  10151. + void operator()(std::istream* stream, const POD& data) const
  10152. + {
  10153. + stream->read(static_cast<char*>(data.address), data.size);
  10154. + }
  10155. + };
  10156. +
  10157. + std::vector<POD> podRef;
  10158. +};
  10159. +
  10160. +//---------------- inline implementation -------------------------
  10161. +template <class T>
  10162. +inline
  10163. +void writePOD(std::ostream& stream, const T& data)
  10164. +{
  10165. + stream.write(reinterpret_cast<const char*>(&data), sizeof(T));
  10166. +}
  10167. +
  10168. +
  10169. +template <class T>
  10170. +inline
  10171. +void readPOD(std::istream& stream, T& data)
  10172. +{
  10173. + stream.read(reinterpret_cast<char*>(&data), sizeof(T));
  10174. +}
  10175. +
  10176. +
  10177. +inline
  10178. +void writeString(std::ostream& stream, const std::string& data)
  10179. +{
  10180. + const size_t stringSize = data.size();
  10181. + writePOD(stream, stringSize);
  10182. + stream.write(data.c_str(), stringSize * sizeof(std::string::value_type));
  10183. +}
  10184. +
  10185. +
  10186. +inline
  10187. +void readString(std::istream& stream, std::string& data)
  10188. +{
  10189. + size_t stringSize = 0;
  10190. + readPOD(stream, stringSize);
  10191. + data.resize(stringSize);
  10192. + stream.read(&data[0], stringSize * sizeof(std::string::value_type));
  10193. +}
  10194. +
  10195. +#endif //SAVE_STATE_H_INCLUDED
  10196. Index: src/unzip.c
  10197. ===================================================================
  10198. --- src/unzip.c (nonexistent)
  10199. +++ src/unzip.c (working copy)
  10200. @@ -0,0 +1,2125 @@
  10201. +/* unzip.c -- IO for uncompress .zip files using zlib
  10202. + Version 1.1, February 14h, 2010
  10203. + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
  10204. +
  10205. + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
  10206. +
  10207. + Modifications of Unzip for Zip64
  10208. + Copyright (C) 2007-2008 Even Rouault
  10209. +
  10210. + Modifications for Zip64 support on both zip and unzip
  10211. + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
  10212. +
  10213. + For more info read MiniZip_info.txt
  10214. +
  10215. +
  10216. + ------------------------------------------------------------------------------------
  10217. + Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
  10218. + compatibility with older software. The following is from the original crypt.c.
  10219. + Code woven in by Terry Thorsen 1/2003.
  10220. +
  10221. + Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
  10222. +
  10223. + See the accompanying file LICENSE, version 2000-Apr-09 or later
  10224. + (the contents of which are also included in zip.h) for terms of use.
  10225. + If, for some reason, all these files are missing, the Info-ZIP license
  10226. + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
  10227. +
  10228. + crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h]
  10229. +
  10230. + The encryption/decryption parts of this source code (as opposed to the
  10231. + non-echoing password parts) were originally written in Europe. The
  10232. + whole source package can be freely distributed, including from the USA.
  10233. + (Prior to January 2000, re-export from the US was a violation of US law.)
  10234. +
  10235. + This encryption code is a direct transcription of the algorithm from
  10236. + Roger Schlafly, described by Phil Katz in the file appnote.txt. This
  10237. + file (appnote.txt) is distributed with the PKZIP program (even in the
  10238. + version without encryption capabilities).
  10239. +
  10240. + ------------------------------------------------------------------------------------
  10241. +
  10242. + Changes in unzip.c
  10243. +
  10244. + 2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos
  10245. + 2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz*
  10246. + 2007-2008 - Even Rouault - Remove old C style function prototypes
  10247. + 2007-2008 - Even Rouault - Add unzip support for ZIP64
  10248. +
  10249. + Copyright (C) 2007-2008 Even Rouault
  10250. +
  10251. +
  10252. + Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again).
  10253. + Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G
  10254. + should only read the compressed/uncompressed size from the Zip64 format if
  10255. + the size from normal header was 0xFFFFFFFF
  10256. + Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant
  10257. + Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required)
  10258. + Patch created by Daniel Borca
  10259. +
  10260. + Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
  10261. +
  10262. + Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson
  10263. +
  10264. +*/
  10265. +
  10266. +
  10267. +#include <stdio.h>
  10268. +#include <stdlib.h>
  10269. +#include <string.h>
  10270. +
  10271. +#ifndef NOUNCRYPT
  10272. + #define NOUNCRYPT
  10273. +#endif
  10274. +
  10275. +#include "zlib.h"
  10276. +#include "unzip.h"
  10277. +
  10278. +#ifdef STDC
  10279. +# include <stddef.h>
  10280. +# include <string.h>
  10281. +# include <stdlib.h>
  10282. +#endif
  10283. +#ifdef NO_ERRNO_H
  10284. + extern int errno;
  10285. +#else
  10286. +# include <errno.h>
  10287. +#endif
  10288. +
  10289. +
  10290. +#ifndef local
  10291. +# define local static
  10292. +#endif
  10293. +/* compile with -Dlocal if your debugger can't find static symbols */
  10294. +
  10295. +
  10296. +#ifndef CASESENSITIVITYDEFAULT_NO
  10297. +# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
  10298. +# define CASESENSITIVITYDEFAULT_NO
  10299. +# endif
  10300. +#endif
  10301. +
  10302. +
  10303. +#ifndef UNZ_BUFSIZE
  10304. +#define UNZ_BUFSIZE (16384)
  10305. +#endif
  10306. +
  10307. +#ifndef UNZ_MAXFILENAMEINZIP
  10308. +#define UNZ_MAXFILENAMEINZIP (256)
  10309. +#endif
  10310. +
  10311. +#ifndef ALLOC
  10312. +# define ALLOC(size) (malloc(size))
  10313. +#endif
  10314. +#ifndef TRYFREE
  10315. +# define TRYFREE(p) {if (p) free(p);}
  10316. +#endif
  10317. +
  10318. +#define SIZECENTRALDIRITEM (0x2e)
  10319. +#define SIZEZIPLOCALHEADER (0x1e)
  10320. +
  10321. +
  10322. +const char unz_copyright[] =
  10323. + " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
  10324. +
  10325. +/* unz_file_info_interntal contain internal info about a file in zipfile*/
  10326. +typedef struct unz_file_info64_internal_s
  10327. +{
  10328. + ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */
  10329. +} unz_file_info64_internal;
  10330. +
  10331. +
  10332. +/* file_in_zip_read_info_s contain internal information about a file in zipfile,
  10333. + when reading and decompress it */
  10334. +typedef struct
  10335. +{
  10336. + char *read_buffer; /* internal buffer for compressed data */
  10337. + z_stream stream; /* zLib stream structure for inflate */
  10338. +
  10339. +#ifdef HAVE_BZIP2
  10340. + bz_stream bstream; /* bzLib stream structure for bziped */
  10341. +#endif
  10342. +
  10343. + ZPOS64_T pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
  10344. + uLong stream_initialised; /* flag set if stream structure is initialised*/
  10345. +
  10346. + ZPOS64_T offset_local_extrafield;/* offset of the local extra field */
  10347. + uInt size_local_extrafield;/* size of the local extra field */
  10348. + ZPOS64_T pos_local_extrafield; /* position in the local extra field in read*/
  10349. + ZPOS64_T total_out_64;
  10350. +
  10351. + uLong crc32; /* crc32 of all data uncompressed */
  10352. + uLong crc32_wait; /* crc32 we must obtain after decompress all */
  10353. + ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */
  10354. + ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/
  10355. + zlib_filefunc64_32_def z_filefunc;
  10356. + voidpf filestream; /* io structore of the zipfile */
  10357. + uLong compression_method; /* compression method (0==store) */
  10358. + ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
  10359. + int raw;
  10360. +} file_in_zip64_read_info_s;
  10361. +
  10362. +
  10363. +/* unz64_s contain internal information about the zipfile
  10364. +*/
  10365. +typedef struct
  10366. +{
  10367. + zlib_filefunc64_32_def z_filefunc;
  10368. + int is64bitOpenFunction;
  10369. + voidpf filestream; /* io structore of the zipfile */
  10370. + unz_global_info64 gi; /* public global information */
  10371. + ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
  10372. + ZPOS64_T num_file; /* number of the current file in the zipfile*/
  10373. + ZPOS64_T pos_in_central_dir; /* pos of the current file in the central dir*/
  10374. + ZPOS64_T current_file_ok; /* flag about the usability of the current file*/
  10375. + ZPOS64_T central_pos; /* position of the beginning of the central dir*/
  10376. +
  10377. + ZPOS64_T size_central_dir; /* size of the central directory */
  10378. + ZPOS64_T offset_central_dir; /* offset of start of central directory with
  10379. + respect to the starting disk number */
  10380. +
  10381. + unz_file_info64 cur_file_info; /* public info about the current file in zip*/
  10382. + unz_file_info64_internal cur_file_info_internal; /* private info about it*/
  10383. + file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current
  10384. + file if we are decompressing it */
  10385. + int encrypted;
  10386. +
  10387. + int isZip64;
  10388. +
  10389. +# ifndef NOUNCRYPT
  10390. + unsigned long keys[3]; /* keys defining the pseudo-random sequence */
  10391. + const unsigned long* pcrc_32_tab;
  10392. +# endif
  10393. +} unz64_s;
  10394. +
  10395. +
  10396. +#ifndef NOUNCRYPT
  10397. +#include "crypt.h"
  10398. +#endif
  10399. +
  10400. +/* ===========================================================================
  10401. + Read a byte from a gz_stream; update next_in and avail_in. Return EOF
  10402. + for end of file.
  10403. + IN assertion: the stream s has been sucessfully opened for reading.
  10404. +*/
  10405. +
  10406. +
  10407. +local int unz64local_getByte OF((
  10408. + const zlib_filefunc64_32_def* pzlib_filefunc_def,
  10409. + voidpf filestream,
  10410. + int *pi));
  10411. +
  10412. +local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)
  10413. +{
  10414. + unsigned char c;
  10415. + int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
  10416. + if (err==1)
  10417. + {
  10418. + *pi = (int)c;
  10419. + return UNZ_OK;
  10420. + }
  10421. + else
  10422. + {
  10423. + if (ZERROR64(*pzlib_filefunc_def,filestream))
  10424. + return UNZ_ERRNO;
  10425. + else
  10426. + return UNZ_EOF;
  10427. + }
  10428. +}
  10429. +
  10430. +
  10431. +/* ===========================================================================
  10432. + Reads a long in LSB order from the given gz_stream. Sets
  10433. +*/
  10434. +local int unz64local_getShort OF((
  10435. + const zlib_filefunc64_32_def* pzlib_filefunc_def,
  10436. + voidpf filestream,
  10437. + uLong *pX));
  10438. +
  10439. +local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def,
  10440. + voidpf filestream,
  10441. + uLong *pX)
  10442. +{
  10443. + uLong x ;
  10444. + int i = 0;
  10445. + int err;
  10446. +
  10447. + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
  10448. + x = (uLong)i;
  10449. +
  10450. + if (err==UNZ_OK)
  10451. + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
  10452. + x |= ((uLong)i)<<8;
  10453. +
  10454. + if (err==UNZ_OK)
  10455. + *pX = x;
  10456. + else
  10457. + *pX = 0;
  10458. + return err;
  10459. +}
  10460. +
  10461. +local int unz64local_getLong OF((
  10462. + const zlib_filefunc64_32_def* pzlib_filefunc_def,
  10463. + voidpf filestream,
  10464. + uLong *pX));
  10465. +
  10466. +local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def,
  10467. + voidpf filestream,
  10468. + uLong *pX)
  10469. +{
  10470. + uLong x ;
  10471. + int i = 0;
  10472. + int err;
  10473. +
  10474. + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
  10475. + x = (uLong)i;
  10476. +
  10477. + if (err==UNZ_OK)
  10478. + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
  10479. + x |= ((uLong)i)<<8;
  10480. +
  10481. + if (err==UNZ_OK)
  10482. + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
  10483. + x |= ((uLong)i)<<16;
  10484. +
  10485. + if (err==UNZ_OK)
  10486. + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
  10487. + x += ((uLong)i)<<24;
  10488. +
  10489. + if (err==UNZ_OK)
  10490. + *pX = x;
  10491. + else
  10492. + *pX = 0;
  10493. + return err;
  10494. +}
  10495. +
  10496. +local int unz64local_getLong64 OF((
  10497. + const zlib_filefunc64_32_def* pzlib_filefunc_def,
  10498. + voidpf filestream,
  10499. + ZPOS64_T *pX));
  10500. +
  10501. +
  10502. +local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def,
  10503. + voidpf filestream,
  10504. + ZPOS64_T *pX)
  10505. +{
  10506. + ZPOS64_T x ;
  10507. + int i = 0;
  10508. + int err;
  10509. +
  10510. + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
  10511. + x = (ZPOS64_T)i;
  10512. +
  10513. + if (err==UNZ_OK)
  10514. + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
  10515. + x |= ((ZPOS64_T)i)<<8;
  10516. +
  10517. + if (err==UNZ_OK)
  10518. + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
  10519. + x |= ((ZPOS64_T)i)<<16;
  10520. +
  10521. + if (err==UNZ_OK)
  10522. + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
  10523. + x |= ((ZPOS64_T)i)<<24;
  10524. +
  10525. + if (err==UNZ_OK)
  10526. + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
  10527. + x |= ((ZPOS64_T)i)<<32;
  10528. +
  10529. + if (err==UNZ_OK)
  10530. + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
  10531. + x |= ((ZPOS64_T)i)<<40;
  10532. +
  10533. + if (err==UNZ_OK)
  10534. + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
  10535. + x |= ((ZPOS64_T)i)<<48;
  10536. +
  10537. + if (err==UNZ_OK)
  10538. + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
  10539. + x |= ((ZPOS64_T)i)<<56;
  10540. +
  10541. + if (err==UNZ_OK)
  10542. + *pX = x;
  10543. + else
  10544. + *pX = 0;
  10545. + return err;
  10546. +}
  10547. +
  10548. +/* My own strcmpi / strcasecmp */
  10549. +local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2)
  10550. +{
  10551. + for (;;)
  10552. + {
  10553. + char c1=*(fileName1++);
  10554. + char c2=*(fileName2++);
  10555. + if ((c1>='a') && (c1<='z'))
  10556. + c1 -= 0x20;
  10557. + if ((c2>='a') && (c2<='z'))
  10558. + c2 -= 0x20;
  10559. + if (c1=='\0')
  10560. + return ((c2=='\0') ? 0 : -1);
  10561. + if (c2=='\0')
  10562. + return 1;
  10563. + if (c1<c2)
  10564. + return -1;
  10565. + if (c1>c2)
  10566. + return 1;
  10567. + }
  10568. +}
  10569. +
  10570. +
  10571. +#ifdef CASESENSITIVITYDEFAULT_NO
  10572. +#define CASESENSITIVITYDEFAULTVALUE 2
  10573. +#else
  10574. +#define CASESENSITIVITYDEFAULTVALUE 1
  10575. +#endif
  10576. +
  10577. +#ifndef STRCMPCASENOSENTIVEFUNCTION
  10578. +#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
  10579. +#endif
  10580. +
  10581. +/*
  10582. + Compare two filename (fileName1,fileName2).
  10583. + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
  10584. + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
  10585. + or strcasecmp)
  10586. + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
  10587. + (like 1 on Unix, 2 on Windows)
  10588. +
  10589. +*/
  10590. +extern int ZEXPORT unzStringFileNameCompare (const char* fileName1,
  10591. + const char* fileName2,
  10592. + int iCaseSensitivity)
  10593. +
  10594. +{
  10595. + if (iCaseSensitivity==0)
  10596. + iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
  10597. +
  10598. + if (iCaseSensitivity==1)
  10599. + return strcmp(fileName1,fileName2);
  10600. +
  10601. + return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
  10602. +}
  10603. +
  10604. +#ifndef BUFREADCOMMENT
  10605. +#define BUFREADCOMMENT (0x400)
  10606. +#endif
  10607. +
  10608. +/*
  10609. + Locate the Central directory of a zipfile (at the end, just before
  10610. + the global comment)
  10611. +*/
  10612. +local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
  10613. +local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
  10614. +{
  10615. + unsigned char* buf;
  10616. + ZPOS64_T uSizeFile;
  10617. + ZPOS64_T uBackRead;
  10618. + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
  10619. + ZPOS64_T uPosFound=0;
  10620. +
  10621. + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
  10622. + return 0;
  10623. +
  10624. +
  10625. + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
  10626. +
  10627. + if (uMaxBack>uSizeFile)
  10628. + uMaxBack = uSizeFile;
  10629. +
  10630. + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
  10631. + if (buf==NULL)
  10632. + return 0;
  10633. +
  10634. + uBackRead = 4;
  10635. + while (uBackRead<uMaxBack)
  10636. + {
  10637. + uLong uReadSize;
  10638. + ZPOS64_T uReadPos ;
  10639. + int i;
  10640. + if (uBackRead+BUFREADCOMMENT>uMaxBack)
  10641. + uBackRead = uMaxBack;
  10642. + else
  10643. + uBackRead+=BUFREADCOMMENT;
  10644. + uReadPos = uSizeFile-uBackRead ;
  10645. +
  10646. + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
  10647. + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
  10648. + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
  10649. + break;
  10650. +
  10651. + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
  10652. + break;
  10653. +
  10654. + for (i=(int)uReadSize-3; (i--)>0;)
  10655. + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
  10656. + ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
  10657. + {
  10658. + uPosFound = uReadPos+i;
  10659. + break;
  10660. + }
  10661. +
  10662. + if (uPosFound!=0)
  10663. + break;
  10664. + }
  10665. + TRYFREE(buf);
  10666. + return uPosFound;
  10667. +}
  10668. +
  10669. +
  10670. +/*
  10671. + Locate the Central directory 64 of a zipfile (at the end, just before
  10672. + the global comment)
  10673. +*/
  10674. +local ZPOS64_T unz64local_SearchCentralDir64 OF((
  10675. + const zlib_filefunc64_32_def* pzlib_filefunc_def,
  10676. + voidpf filestream));
  10677. +
  10678. +local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def,
  10679. + voidpf filestream)
  10680. +{
  10681. + unsigned char* buf;
  10682. + ZPOS64_T uSizeFile;
  10683. + ZPOS64_T uBackRead;
  10684. + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
  10685. + ZPOS64_T uPosFound=0;
  10686. + uLong uL;
  10687. + ZPOS64_T relativeOffset;
  10688. +
  10689. + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
  10690. + return 0;
  10691. +
  10692. +
  10693. + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
  10694. +
  10695. + if (uMaxBack>uSizeFile)
  10696. + uMaxBack = uSizeFile;
  10697. +
  10698. + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
  10699. + if (buf==NULL)
  10700. + return 0;
  10701. +
  10702. + uBackRead = 4;
  10703. + while (uBackRead<uMaxBack)
  10704. + {
  10705. + uLong uReadSize;
  10706. + ZPOS64_T uReadPos;
  10707. + int i;
  10708. + if (uBackRead+BUFREADCOMMENT>uMaxBack)
  10709. + uBackRead = uMaxBack;
  10710. + else
  10711. + uBackRead+=BUFREADCOMMENT;
  10712. + uReadPos = uSizeFile-uBackRead ;
  10713. +
  10714. + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
  10715. + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
  10716. + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
  10717. + break;
  10718. +
  10719. + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
  10720. + break;
  10721. +
  10722. + for (i=(int)uReadSize-3; (i--)>0;)
  10723. + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
  10724. + ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
  10725. + {
  10726. + uPosFound = uReadPos+i;
  10727. + break;
  10728. + }
  10729. +
  10730. + if (uPosFound!=0)
  10731. + break;
  10732. + }
  10733. + TRYFREE(buf);
  10734. + if (uPosFound == 0)
  10735. + return 0;
  10736. +
  10737. + /* Zip64 end of central directory locator */
  10738. + if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
  10739. + return 0;
  10740. +
  10741. + /* the signature, already checked */
  10742. + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
  10743. + return 0;
  10744. +
  10745. + /* number of the disk with the start of the zip64 end of central directory */
  10746. + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
  10747. + return 0;
  10748. + if (uL != 0)
  10749. + return 0;
  10750. +
  10751. + /* relative offset of the zip64 end of central directory record */
  10752. + if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK)
  10753. + return 0;
  10754. +
  10755. + /* total number of disks */
  10756. + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
  10757. + return 0;
  10758. + if (uL != 1)
  10759. + return 0;
  10760. +
  10761. + /* Goto end of central directory record */
  10762. + if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
  10763. + return 0;
  10764. +
  10765. + /* the signature */
  10766. + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
  10767. + return 0;
  10768. +
  10769. + if (uL != 0x06064b50)
  10770. + return 0;
  10771. +
  10772. + return relativeOffset;
  10773. +}
  10774. +
  10775. +/*
  10776. + Open a Zip file. path contain the full pathname (by example,
  10777. + on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
  10778. + "zlib/zlib114.zip".
  10779. + If the zipfile cannot be opened (file doesn't exist or in not valid), the
  10780. + return value is NULL.
  10781. + Else, the return value is a unzFile Handle, usable with other function
  10782. + of this unzip package.
  10783. +*/
  10784. +local unzFile unzOpenInternal (const void *path,
  10785. + zlib_filefunc64_32_def* pzlib_filefunc64_32_def,
  10786. + int is64bitOpenFunction)
  10787. +{
  10788. + unz64_s us;
  10789. + unz64_s *s;
  10790. + ZPOS64_T central_pos;
  10791. + uLong uL;
  10792. +
  10793. + uLong number_disk; /* number of the current dist, used for
  10794. + spaning ZIP, unsupported, always 0*/
  10795. + uLong number_disk_with_CD; /* number the the disk with central dir, used
  10796. + for spaning ZIP, unsupported, always 0*/
  10797. + ZPOS64_T number_entry_CD; /* total number of entries in
  10798. + the central dir
  10799. + (same than number_entry on nospan) */
  10800. +
  10801. + int err=UNZ_OK;
  10802. +
  10803. + if (unz_copyright[0]!=' ')
  10804. + return NULL;
  10805. +
  10806. + us.z_filefunc.zseek32_file = NULL;
  10807. + us.z_filefunc.ztell32_file = NULL;
  10808. + if (pzlib_filefunc64_32_def==NULL)
  10809. + fill_fopen64_filefunc(&us.z_filefunc.zfile_func64);
  10810. + else
  10811. + us.z_filefunc = *pzlib_filefunc64_32_def;
  10812. + us.is64bitOpenFunction = is64bitOpenFunction;
  10813. +
  10814. +
  10815. +
  10816. + us.filestream = ZOPEN64(us.z_filefunc,
  10817. + path,
  10818. + ZLIB_FILEFUNC_MODE_READ |
  10819. + ZLIB_FILEFUNC_MODE_EXISTING);
  10820. + if (us.filestream==NULL)
  10821. + return NULL;
  10822. +
  10823. + central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream);
  10824. + if (central_pos)
  10825. + {
  10826. + uLong uS;
  10827. + ZPOS64_T uL64;
  10828. +
  10829. + us.isZip64 = 1;
  10830. +
  10831. + if (ZSEEK64(us.z_filefunc, us.filestream,
  10832. + central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
  10833. + err=UNZ_ERRNO;
  10834. +
  10835. + /* the signature, already checked */
  10836. + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
  10837. + err=UNZ_ERRNO;
  10838. +
  10839. + /* size of zip64 end of central directory record */
  10840. + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK)
  10841. + err=UNZ_ERRNO;
  10842. +
  10843. + /* version made by */
  10844. + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
  10845. + err=UNZ_ERRNO;
  10846. +
  10847. + /* version needed to extract */
  10848. + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
  10849. + err=UNZ_ERRNO;
  10850. +
  10851. + /* number of this disk */
  10852. + if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
  10853. + err=UNZ_ERRNO;
  10854. +
  10855. + /* number of the disk with the start of the central directory */
  10856. + if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
  10857. + err=UNZ_ERRNO;
  10858. +
  10859. + /* total number of entries in the central directory on this disk */
  10860. + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
  10861. + err=UNZ_ERRNO;
  10862. +
  10863. + /* total number of entries in the central directory */
  10864. + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
  10865. + err=UNZ_ERRNO;
  10866. +
  10867. + if ((number_entry_CD!=us.gi.number_entry) ||
  10868. + (number_disk_with_CD!=0) ||
  10869. + (number_disk!=0))
  10870. + err=UNZ_BADZIPFILE;
  10871. +
  10872. + /* size of the central directory */
  10873. + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
  10874. + err=UNZ_ERRNO;
  10875. +
  10876. + /* offset of start of central directory with respect to the
  10877. + starting disk number */
  10878. + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
  10879. + err=UNZ_ERRNO;
  10880. +
  10881. + us.gi.size_comment = 0;
  10882. + }
  10883. + else
  10884. + {
  10885. + central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream);
  10886. + if (central_pos==0)
  10887. + err=UNZ_ERRNO;
  10888. +
  10889. + us.isZip64 = 0;
  10890. +
  10891. + if (ZSEEK64(us.z_filefunc, us.filestream,
  10892. + central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
  10893. + err=UNZ_ERRNO;
  10894. +
  10895. + /* the signature, already checked */
  10896. + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
  10897. + err=UNZ_ERRNO;
  10898. +
  10899. + /* number of this disk */
  10900. + if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
  10901. + err=UNZ_ERRNO;
  10902. +
  10903. + /* number of the disk with the start of the central directory */
  10904. + if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
  10905. + err=UNZ_ERRNO;
  10906. +
  10907. + /* total number of entries in the central dir on this disk */
  10908. + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
  10909. + err=UNZ_ERRNO;
  10910. + us.gi.number_entry = uL;
  10911. +
  10912. + /* total number of entries in the central dir */
  10913. + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
  10914. + err=UNZ_ERRNO;
  10915. + number_entry_CD = uL;
  10916. +
  10917. + if ((number_entry_CD!=us.gi.number_entry) ||
  10918. + (number_disk_with_CD!=0) ||
  10919. + (number_disk!=0))
  10920. + err=UNZ_BADZIPFILE;
  10921. +
  10922. + /* size of the central directory */
  10923. + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
  10924. + err=UNZ_ERRNO;
  10925. + us.size_central_dir = uL;
  10926. +
  10927. + /* offset of start of central directory with respect to the
  10928. + starting disk number */
  10929. + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
  10930. + err=UNZ_ERRNO;
  10931. + us.offset_central_dir = uL;
  10932. +
  10933. + /* zipfile comment length */
  10934. + if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
  10935. + err=UNZ_ERRNO;
  10936. + }
  10937. +
  10938. + if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
  10939. + (err==UNZ_OK))
  10940. + err=UNZ_BADZIPFILE;
  10941. +
  10942. + if (err!=UNZ_OK)
  10943. + {
  10944. + ZCLOSE64(us.z_filefunc, us.filestream);
  10945. + return NULL;
  10946. + }
  10947. +
  10948. + us.byte_before_the_zipfile = central_pos -
  10949. + (us.offset_central_dir+us.size_central_dir);
  10950. + us.central_pos = central_pos;
  10951. + us.pfile_in_zip_read = NULL;
  10952. + us.encrypted = 0;
  10953. +
  10954. +
  10955. + s=(unz64_s*)ALLOC(sizeof(unz64_s));
  10956. + if( s != NULL)
  10957. + {
  10958. + *s=us;
  10959. + unzGoToFirstFile((unzFile)s);
  10960. + }
  10961. + return (unzFile)s;
  10962. +}
  10963. +
  10964. +
  10965. +extern unzFile ZEXPORT unzOpen2 (const char *path,
  10966. + zlib_filefunc_def* pzlib_filefunc32_def)
  10967. +{
  10968. + if (pzlib_filefunc32_def != NULL)
  10969. + {
  10970. + zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
  10971. + fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
  10972. + return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 0);
  10973. + }
  10974. + else
  10975. + return unzOpenInternal(path, NULL, 0);
  10976. +}
  10977. +
  10978. +extern unzFile ZEXPORT unzOpen2_64 (const void *path,
  10979. + zlib_filefunc64_def* pzlib_filefunc_def)
  10980. +{
  10981. + if (pzlib_filefunc_def != NULL)
  10982. + {
  10983. + zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
  10984. + zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
  10985. + zlib_filefunc64_32_def_fill.ztell32_file = NULL;
  10986. + zlib_filefunc64_32_def_fill.zseek32_file = NULL;
  10987. + return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 1);
  10988. + }
  10989. + else
  10990. + return unzOpenInternal(path, NULL, 1);
  10991. +}
  10992. +
  10993. +extern unzFile ZEXPORT unzOpen (const char *path)
  10994. +{
  10995. + return unzOpenInternal(path, NULL, 0);
  10996. +}
  10997. +
  10998. +extern unzFile ZEXPORT unzOpen64 (const void *path)
  10999. +{
  11000. + return unzOpenInternal(path, NULL, 1);
  11001. +}
  11002. +
  11003. +/*
  11004. + Close a ZipFile opened with unzipOpen.
  11005. + If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
  11006. + these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
  11007. + return UNZ_OK if there is no problem. */
  11008. +extern int ZEXPORT unzClose (unzFile file)
  11009. +{
  11010. + unz64_s* s;
  11011. + if (file==NULL)
  11012. + return UNZ_PARAMERROR;
  11013. + s=(unz64_s*)file;
  11014. +
  11015. + if (s->pfile_in_zip_read!=NULL)
  11016. + unzCloseCurrentFile(file);
  11017. +
  11018. + ZCLOSE64(s->z_filefunc, s->filestream);
  11019. + TRYFREE(s);
  11020. + return UNZ_OK;
  11021. +}
  11022. +
  11023. +
  11024. +/*
  11025. + Write info about the ZipFile in the *pglobal_info structure.
  11026. + No preparation of the structure is needed
  11027. + return UNZ_OK if there is no problem. */
  11028. +extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info)
  11029. +{
  11030. + unz64_s* s;
  11031. + if (file==NULL)
  11032. + return UNZ_PARAMERROR;
  11033. + s=(unz64_s*)file;
  11034. + *pglobal_info=s->gi;
  11035. + return UNZ_OK;
  11036. +}
  11037. +
  11038. +extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32)
  11039. +{
  11040. + unz64_s* s;
  11041. + if (file==NULL)
  11042. + return UNZ_PARAMERROR;
  11043. + s=(unz64_s*)file;
  11044. + /* to do : check if number_entry is not truncated */
  11045. + pglobal_info32->number_entry = (uLong)s->gi.number_entry;
  11046. + pglobal_info32->size_comment = s->gi.size_comment;
  11047. + return UNZ_OK;
  11048. +}
  11049. +/*
  11050. + Translate date/time from Dos format to tm_unz (readable more easilty)
  11051. +*/
  11052. +local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm)
  11053. +{
  11054. + ZPOS64_T uDate;
  11055. + uDate = (ZPOS64_T)(ulDosDate>>16);
  11056. + ptm->tm_mday = (uInt)(uDate&0x1f) ;
  11057. + ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
  11058. + ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
  11059. +
  11060. + ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
  11061. + ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
  11062. + ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
  11063. +}
  11064. +
  11065. +/*
  11066. + Get Info about the current file in the zipfile, with internal only info
  11067. +*/
  11068. +local int unz64local_GetCurrentFileInfoInternal OF((unzFile file,
  11069. + unz_file_info64 *pfile_info,
  11070. + unz_file_info64_internal
  11071. + *pfile_info_internal,
  11072. + char *szFileName,
  11073. + uLong fileNameBufferSize,
  11074. + void *extraField,
  11075. + uLong extraFieldBufferSize,
  11076. + char *szComment,
  11077. + uLong commentBufferSize));
  11078. +
  11079. +local int unz64local_GetCurrentFileInfoInternal (unzFile file,
  11080. + unz_file_info64 *pfile_info,
  11081. + unz_file_info64_internal
  11082. + *pfile_info_internal,
  11083. + char *szFileName,
  11084. + uLong fileNameBufferSize,
  11085. + void *extraField,
  11086. + uLong extraFieldBufferSize,
  11087. + char *szComment,
  11088. + uLong commentBufferSize)
  11089. +{
  11090. + unz64_s* s;
  11091. + unz_file_info64 file_info;
  11092. + unz_file_info64_internal file_info_internal;
  11093. + int err=UNZ_OK;
  11094. + uLong uMagic;
  11095. + long lSeek=0;
  11096. + uLong uL;
  11097. +
  11098. + if (file==NULL)
  11099. + return UNZ_PARAMERROR;
  11100. + s=(unz64_s*)file;
  11101. + if (ZSEEK64(s->z_filefunc, s->filestream,
  11102. + s->pos_in_central_dir+s->byte_before_the_zipfile,
  11103. + ZLIB_FILEFUNC_SEEK_SET)!=0)
  11104. + err=UNZ_ERRNO;
  11105. +
  11106. +
  11107. + /* we check the magic */
  11108. + if (err==UNZ_OK)
  11109. + {
  11110. + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
  11111. + err=UNZ_ERRNO;
  11112. + else if (uMagic!=0x02014b50)
  11113. + err=UNZ_BADZIPFILE;
  11114. + }
  11115. +
  11116. + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
  11117. + err=UNZ_ERRNO;
  11118. +
  11119. + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
  11120. + err=UNZ_ERRNO;
  11121. +
  11122. + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
  11123. + err=UNZ_ERRNO;
  11124. +
  11125. + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
  11126. + err=UNZ_ERRNO;
  11127. +
  11128. + if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
  11129. + err=UNZ_ERRNO;
  11130. +
  11131. + unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
  11132. +
  11133. + if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
  11134. + err=UNZ_ERRNO;
  11135. +
  11136. + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
  11137. + err=UNZ_ERRNO;
  11138. + file_info.compressed_size = uL;
  11139. +
  11140. + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
  11141. + err=UNZ_ERRNO;
  11142. + file_info.uncompressed_size = uL;
  11143. +
  11144. + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
  11145. + err=UNZ_ERRNO;
  11146. +
  11147. + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
  11148. + err=UNZ_ERRNO;
  11149. +
  11150. + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
  11151. + err=UNZ_ERRNO;
  11152. +
  11153. + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
  11154. + err=UNZ_ERRNO;
  11155. +
  11156. + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
  11157. + err=UNZ_ERRNO;
  11158. +
  11159. + if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
  11160. + err=UNZ_ERRNO;
  11161. +
  11162. + // relative offset of local header
  11163. + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
  11164. + err=UNZ_ERRNO;
  11165. + file_info_internal.offset_curfile = uL;
  11166. +
  11167. + lSeek+=file_info.size_filename;
  11168. + if ((err==UNZ_OK) && (szFileName!=NULL))
  11169. + {
  11170. + uLong uSizeRead ;
  11171. + if (file_info.size_filename<fileNameBufferSize)
  11172. + {
  11173. + *(szFileName+file_info.size_filename)='\0';
  11174. + uSizeRead = file_info.size_filename;
  11175. + }
  11176. + else
  11177. + uSizeRead = fileNameBufferSize;
  11178. +
  11179. + if ((file_info.size_filename>0) && (fileNameBufferSize>0))
  11180. + if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
  11181. + err=UNZ_ERRNO;
  11182. + lSeek -= uSizeRead;
  11183. + }
  11184. +
  11185. + // Read extrafield
  11186. + if ((err==UNZ_OK) && (extraField!=NULL))
  11187. + {
  11188. + ZPOS64_T uSizeRead ;
  11189. + if (file_info.size_file_extra<extraFieldBufferSize)
  11190. + uSizeRead = file_info.size_file_extra;
  11191. + else
  11192. + uSizeRead = extraFieldBufferSize;
  11193. +
  11194. + if (lSeek!=0)
  11195. + {
  11196. + if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
  11197. + lSeek=0;
  11198. + else
  11199. + err=UNZ_ERRNO;
  11200. + }
  11201. +
  11202. + if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
  11203. + if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead)
  11204. + err=UNZ_ERRNO;
  11205. +
  11206. + lSeek += file_info.size_file_extra - (uLong)uSizeRead;
  11207. + }
  11208. + else
  11209. + lSeek += file_info.size_file_extra;
  11210. +
  11211. +
  11212. + if ((err==UNZ_OK) && (file_info.size_file_extra != 0))
  11213. + {
  11214. + uLong acc = 0;
  11215. +
  11216. + // since lSeek now points to after the extra field we need to move back
  11217. + lSeek -= file_info.size_file_extra;
  11218. +
  11219. + if (lSeek!=0)
  11220. + {
  11221. + if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
  11222. + lSeek=0;
  11223. + else
  11224. + err=UNZ_ERRNO;
  11225. + }
  11226. +
  11227. + while(acc < file_info.size_file_extra)
  11228. + {
  11229. + uLong headerId;
  11230. + uLong dataSize;
  11231. +
  11232. + if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK)
  11233. + err=UNZ_ERRNO;
  11234. +
  11235. + if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK)
  11236. + err=UNZ_ERRNO;
  11237. +
  11238. + /* ZIP64 extra fields */
  11239. + if (headerId == 0x0001)
  11240. + {
  11241. + uLong uL;
  11242. +
  11243. + if(file_info.uncompressed_size == (ZPOS64_T)(unsigned long)-1)
  11244. + {
  11245. + if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
  11246. + err=UNZ_ERRNO;
  11247. + }
  11248. +
  11249. + if(file_info.compressed_size == (ZPOS64_T)(unsigned long)-1)
  11250. + {
  11251. + if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
  11252. + err=UNZ_ERRNO;
  11253. + }
  11254. +
  11255. + if(file_info_internal.offset_curfile == (ZPOS64_T)(unsigned long)-1)
  11256. + {
  11257. + /* Relative Header offset */
  11258. + if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
  11259. + err=UNZ_ERRNO;
  11260. + }
  11261. +
  11262. + if(file_info.disk_num_start == (unsigned long)-1)
  11263. + {
  11264. + /* Disk Start Number */
  11265. + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
  11266. + err=UNZ_ERRNO;
  11267. + }
  11268. +
  11269. + }
  11270. + else
  11271. + {
  11272. + if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0)
  11273. + err=UNZ_ERRNO;
  11274. + }
  11275. +
  11276. + acc += 2 + 2 + dataSize;
  11277. + }
  11278. + }
  11279. +
  11280. + if ((err==UNZ_OK) && (szComment!=NULL))
  11281. + {
  11282. + uLong uSizeRead ;
  11283. + if (file_info.size_file_comment<commentBufferSize)
  11284. + {
  11285. + *(szComment+file_info.size_file_comment)='\0';
  11286. + uSizeRead = file_info.size_file_comment;
  11287. + }
  11288. + else
  11289. + uSizeRead = commentBufferSize;
  11290. +
  11291. + if (lSeek!=0)
  11292. + {
  11293. + if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
  11294. + lSeek=0;
  11295. + else
  11296. + err=UNZ_ERRNO;
  11297. + }
  11298. +
  11299. + if ((file_info.size_file_comment>0) && (commentBufferSize>0))
  11300. + if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
  11301. + err=UNZ_ERRNO;
  11302. + lSeek+=file_info.size_file_comment - uSizeRead;
  11303. + }
  11304. + else
  11305. + lSeek+=file_info.size_file_comment;
  11306. +
  11307. +
  11308. + if ((err==UNZ_OK) && (pfile_info!=NULL))
  11309. + *pfile_info=file_info;
  11310. +
  11311. + if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
  11312. + *pfile_info_internal=file_info_internal;
  11313. +
  11314. + return err;
  11315. +}
  11316. +
  11317. +
  11318. +
  11319. +/*
  11320. + Write info about the ZipFile in the *pglobal_info structure.
  11321. + No preparation of the structure is needed
  11322. + return UNZ_OK if there is no problem.
  11323. +*/
  11324. +extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file,
  11325. + unz_file_info64 * pfile_info,
  11326. + char * szFileName, uLong fileNameBufferSize,
  11327. + void *extraField, uLong extraFieldBufferSize,
  11328. + char* szComment, uLong commentBufferSize)
  11329. +{
  11330. + return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL,
  11331. + szFileName,fileNameBufferSize,
  11332. + extraField,extraFieldBufferSize,
  11333. + szComment,commentBufferSize);
  11334. +}
  11335. +
  11336. +extern int ZEXPORT unzGetCurrentFileInfo (unzFile file,
  11337. + unz_file_info * pfile_info,
  11338. + char * szFileName, uLong fileNameBufferSize,
  11339. + void *extraField, uLong extraFieldBufferSize,
  11340. + char* szComment, uLong commentBufferSize)
  11341. +{
  11342. + int err;
  11343. + unz_file_info64 file_info64;
  11344. + err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL,
  11345. + szFileName,fileNameBufferSize,
  11346. + extraField,extraFieldBufferSize,
  11347. + szComment,commentBufferSize);
  11348. + if (err==UNZ_OK)
  11349. + {
  11350. + pfile_info->version = file_info64.version;
  11351. + pfile_info->version_needed = file_info64.version_needed;
  11352. + pfile_info->flag = file_info64.flag;
  11353. + pfile_info->compression_method = file_info64.compression_method;
  11354. + pfile_info->dosDate = file_info64.dosDate;
  11355. + pfile_info->crc = file_info64.crc;
  11356. +
  11357. + pfile_info->size_filename = file_info64.size_filename;
  11358. + pfile_info->size_file_extra = file_info64.size_file_extra;
  11359. + pfile_info->size_file_comment = file_info64.size_file_comment;
  11360. +
  11361. + pfile_info->disk_num_start = file_info64.disk_num_start;
  11362. + pfile_info->internal_fa = file_info64.internal_fa;
  11363. + pfile_info->external_fa = file_info64.external_fa;
  11364. +
  11365. + pfile_info->tmu_date = file_info64.tmu_date,
  11366. +
  11367. +
  11368. + pfile_info->compressed_size = (uLong)file_info64.compressed_size;
  11369. + pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size;
  11370. +
  11371. + }
  11372. + return err;
  11373. +}
  11374. +/*
  11375. + Set the current file of the zipfile to the first file.
  11376. + return UNZ_OK if there is no problem
  11377. +*/
  11378. +extern int ZEXPORT unzGoToFirstFile (unzFile file)
  11379. +{
  11380. + int err=UNZ_OK;
  11381. + unz64_s* s;
  11382. + if (file==NULL)
  11383. + return UNZ_PARAMERROR;
  11384. + s=(unz64_s*)file;
  11385. + s->pos_in_central_dir=s->offset_central_dir;
  11386. + s->num_file=0;
  11387. + err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
  11388. + &s->cur_file_info_internal,
  11389. + NULL,0,NULL,0,NULL,0);
  11390. + s->current_file_ok = (err == UNZ_OK);
  11391. + return err;
  11392. +}
  11393. +
  11394. +/*
  11395. + Set the current file of the zipfile to the next file.
  11396. + return UNZ_OK if there is no problem
  11397. + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
  11398. +*/
  11399. +extern int ZEXPORT unzGoToNextFile (unzFile file)
  11400. +{
  11401. + unz64_s* s;
  11402. + int err;
  11403. +
  11404. + if (file==NULL)
  11405. + return UNZ_PARAMERROR;
  11406. + s=(unz64_s*)file;
  11407. + if (!s->current_file_ok)
  11408. + return UNZ_END_OF_LIST_OF_FILE;
  11409. + if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */
  11410. + if (s->num_file+1==s->gi.number_entry)
  11411. + return UNZ_END_OF_LIST_OF_FILE;
  11412. +
  11413. + s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
  11414. + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
  11415. + s->num_file++;
  11416. + err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
  11417. + &s->cur_file_info_internal,
  11418. + NULL,0,NULL,0,NULL,0);
  11419. + s->current_file_ok = (err == UNZ_OK);
  11420. + return err;
  11421. +}
  11422. +
  11423. +
  11424. +/*
  11425. + Try locate the file szFileName in the zipfile.
  11426. + For the iCaseSensitivity signification, see unzipStringFileNameCompare
  11427. +
  11428. + return value :
  11429. + UNZ_OK if the file is found. It becomes the current file.
  11430. + UNZ_END_OF_LIST_OF_FILE if the file is not found
  11431. +*/
  11432. +extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity)
  11433. +{
  11434. + unz64_s* s;
  11435. + int err;
  11436. +
  11437. + /* We remember the 'current' position in the file so that we can jump
  11438. + * back there if we fail.
  11439. + */
  11440. + unz_file_info64 cur_file_infoSaved;
  11441. + unz_file_info64_internal cur_file_info_internalSaved;
  11442. + ZPOS64_T num_fileSaved;
  11443. + ZPOS64_T pos_in_central_dirSaved;
  11444. +
  11445. +
  11446. + if (file==NULL)
  11447. + return UNZ_PARAMERROR;
  11448. +
  11449. + if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
  11450. + return UNZ_PARAMERROR;
  11451. +
  11452. + s=(unz64_s*)file;
  11453. + if (!s->current_file_ok)
  11454. + return UNZ_END_OF_LIST_OF_FILE;
  11455. +
  11456. + /* Save the current state */
  11457. + num_fileSaved = s->num_file;
  11458. + pos_in_central_dirSaved = s->pos_in_central_dir;
  11459. + cur_file_infoSaved = s->cur_file_info;
  11460. + cur_file_info_internalSaved = s->cur_file_info_internal;
  11461. +
  11462. + err = unzGoToFirstFile(file);
  11463. +
  11464. + while (err == UNZ_OK)
  11465. + {
  11466. + char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
  11467. + err = unzGetCurrentFileInfo64(file,NULL,
  11468. + szCurrentFileName,sizeof(szCurrentFileName)-1,
  11469. + NULL,0,NULL,0);
  11470. + if (err == UNZ_OK)
  11471. + {
  11472. + if (unzStringFileNameCompare(szCurrentFileName,
  11473. + szFileName,iCaseSensitivity)==0)
  11474. + return UNZ_OK;
  11475. + err = unzGoToNextFile(file);
  11476. + }
  11477. + }
  11478. +
  11479. + /* We failed, so restore the state of the 'current file' to where we
  11480. + * were.
  11481. + */
  11482. + s->num_file = num_fileSaved ;
  11483. + s->pos_in_central_dir = pos_in_central_dirSaved ;
  11484. + s->cur_file_info = cur_file_infoSaved;
  11485. + s->cur_file_info_internal = cur_file_info_internalSaved;
  11486. + return err;
  11487. +}
  11488. +
  11489. +
  11490. +/*
  11491. +///////////////////////////////////////////
  11492. +// Contributed by Ryan Haksi (mailto://[email protected])
  11493. +// I need random access
  11494. +//
  11495. +// Further optimization could be realized by adding an ability
  11496. +// to cache the directory in memory. The goal being a single
  11497. +// comprehensive file read to put the file I need in a memory.
  11498. +*/
  11499. +
  11500. +/*
  11501. +typedef struct unz_file_pos_s
  11502. +{
  11503. + ZPOS64_T pos_in_zip_directory; // offset in file
  11504. + ZPOS64_T num_of_file; // # of file
  11505. +} unz_file_pos;
  11506. +*/
  11507. +
  11508. +extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos)
  11509. +{
  11510. + unz64_s* s;
  11511. +
  11512. + if (file==NULL || file_pos==NULL)
  11513. + return UNZ_PARAMERROR;
  11514. + s=(unz64_s*)file;
  11515. + if (!s->current_file_ok)
  11516. + return UNZ_END_OF_LIST_OF_FILE;
  11517. +
  11518. + file_pos->pos_in_zip_directory = s->pos_in_central_dir;
  11519. + file_pos->num_of_file = s->num_file;
  11520. +
  11521. + return UNZ_OK;
  11522. +}
  11523. +
  11524. +extern int ZEXPORT unzGetFilePos(
  11525. + unzFile file,
  11526. + unz_file_pos* file_pos)
  11527. +{
  11528. + unz64_file_pos file_pos64;
  11529. + int err = unzGetFilePos64(file,&file_pos64);
  11530. + if (err==UNZ_OK)
  11531. + {
  11532. + file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory;
  11533. + file_pos->num_of_file = (uLong)file_pos64.num_of_file;
  11534. + }
  11535. + return err;
  11536. +}
  11537. +
  11538. +extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos)
  11539. +{
  11540. + unz64_s* s;
  11541. + int err;
  11542. +
  11543. + if (file==NULL || file_pos==NULL)
  11544. + return UNZ_PARAMERROR;
  11545. + s=(unz64_s*)file;
  11546. +
  11547. + /* jump to the right spot */
  11548. + s->pos_in_central_dir = file_pos->pos_in_zip_directory;
  11549. + s->num_file = file_pos->num_of_file;
  11550. +
  11551. + /* set the current file */
  11552. + err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
  11553. + &s->cur_file_info_internal,
  11554. + NULL,0,NULL,0,NULL,0);
  11555. + /* return results */
  11556. + s->current_file_ok = (err == UNZ_OK);
  11557. + return err;
  11558. +}
  11559. +
  11560. +extern int ZEXPORT unzGoToFilePos(
  11561. + unzFile file,
  11562. + unz_file_pos* file_pos)
  11563. +{
  11564. + unz64_file_pos file_pos64;
  11565. + if (file_pos == NULL)
  11566. + return UNZ_PARAMERROR;
  11567. +
  11568. + file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory;
  11569. + file_pos64.num_of_file = file_pos->num_of_file;
  11570. + return unzGoToFilePos64(file,&file_pos64);
  11571. +}
  11572. +
  11573. +/*
  11574. +// Unzip Helper Functions - should be here?
  11575. +///////////////////////////////////////////
  11576. +*/
  11577. +
  11578. +/*
  11579. + Read the local header of the current zipfile
  11580. + Check the coherency of the local header and info in the end of central
  11581. + directory about this file
  11582. + store in *piSizeVar the size of extra info in local header
  11583. + (filename and size of extra field data)
  11584. +*/
  11585. +local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar,
  11586. + ZPOS64_T * poffset_local_extrafield,
  11587. + uInt * psize_local_extrafield)
  11588. +{
  11589. + uLong uMagic,uData,uFlags;
  11590. + uLong size_filename;
  11591. + uLong size_extra_field;
  11592. + int err=UNZ_OK;
  11593. +
  11594. + *piSizeVar = 0;
  11595. + *poffset_local_extrafield = 0;
  11596. + *psize_local_extrafield = 0;
  11597. +
  11598. + if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
  11599. + s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
  11600. + return UNZ_ERRNO;
  11601. +
  11602. +
  11603. + if (err==UNZ_OK)
  11604. + {
  11605. + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
  11606. + err=UNZ_ERRNO;
  11607. + else if (uMagic!=0x04034b50)
  11608. + err=UNZ_BADZIPFILE;
  11609. + }
  11610. +
  11611. + if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
  11612. + err=UNZ_ERRNO;
  11613. +/*
  11614. + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
  11615. + err=UNZ_BADZIPFILE;
  11616. +*/
  11617. + if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
  11618. + err=UNZ_ERRNO;
  11619. +
  11620. + if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
  11621. + err=UNZ_ERRNO;
  11622. + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
  11623. + err=UNZ_BADZIPFILE;
  11624. +
  11625. + if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
  11626. +/* #ifdef HAVE_BZIP2 */
  11627. + (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
  11628. +/* #endif */
  11629. + (s->cur_file_info.compression_method!=Z_DEFLATED))
  11630. + err=UNZ_BADZIPFILE;
  11631. +
  11632. + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
  11633. + err=UNZ_ERRNO;
  11634. +
  11635. + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
  11636. + err=UNZ_ERRNO;
  11637. + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0))
  11638. + err=UNZ_BADZIPFILE;
  11639. +
  11640. + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
  11641. + err=UNZ_ERRNO;
  11642. + else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0))
  11643. + err=UNZ_BADZIPFILE;
  11644. +
  11645. + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
  11646. + err=UNZ_ERRNO;
  11647. + else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0))
  11648. + err=UNZ_BADZIPFILE;
  11649. +
  11650. + if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
  11651. + err=UNZ_ERRNO;
  11652. + else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
  11653. + err=UNZ_BADZIPFILE;
  11654. +
  11655. + *piSizeVar += (uInt)size_filename;
  11656. +
  11657. + if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
  11658. + err=UNZ_ERRNO;
  11659. + *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
  11660. + SIZEZIPLOCALHEADER + size_filename;
  11661. + *psize_local_extrafield = (uInt)size_extra_field;
  11662. +
  11663. + *piSizeVar += (uInt)size_extra_field;
  11664. +
  11665. + return err;
  11666. +}
  11667. +
  11668. +/*
  11669. + Open for reading data the current file in the zipfile.
  11670. + If there is no error and the file is opened, the return value is UNZ_OK.
  11671. +*/
  11672. +extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,
  11673. + int* level, int raw, const char* password)
  11674. +{
  11675. + int err=UNZ_OK;
  11676. + uInt iSizeVar;
  11677. + unz64_s* s;
  11678. + file_in_zip64_read_info_s* pfile_in_zip_read_info;
  11679. + ZPOS64_T offset_local_extrafield; /* offset of the local extra field */
  11680. + uInt size_local_extrafield; /* size of the local extra field */
  11681. +# ifndef NOUNCRYPT
  11682. + char source[12];
  11683. +# else
  11684. + if (password != NULL)
  11685. + return UNZ_PARAMERROR;
  11686. +# endif
  11687. +
  11688. + if (file==NULL)
  11689. + return UNZ_PARAMERROR;
  11690. + s=(unz64_s*)file;
  11691. + if (!s->current_file_ok)
  11692. + return UNZ_PARAMERROR;
  11693. +
  11694. + if (s->pfile_in_zip_read != NULL)
  11695. + unzCloseCurrentFile(file);
  11696. +
  11697. + if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
  11698. + return UNZ_BADZIPFILE;
  11699. +
  11700. + pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s));
  11701. + if (pfile_in_zip_read_info==NULL)
  11702. + return UNZ_INTERNALERROR;
  11703. +
  11704. + pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
  11705. + pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
  11706. + pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
  11707. + pfile_in_zip_read_info->pos_local_extrafield=0;
  11708. + pfile_in_zip_read_info->raw=raw;
  11709. +
  11710. + if (pfile_in_zip_read_info->read_buffer==NULL)
  11711. + {
  11712. + TRYFREE(pfile_in_zip_read_info);
  11713. + return UNZ_INTERNALERROR;
  11714. + }
  11715. +
  11716. + pfile_in_zip_read_info->stream_initialised=0;
  11717. +
  11718. + if (method!=NULL)
  11719. + *method = (int)s->cur_file_info.compression_method;
  11720. +
  11721. + if (level!=NULL)
  11722. + {
  11723. + *level = 6;
  11724. + switch (s->cur_file_info.flag & 0x06)
  11725. + {
  11726. + case 6 : *level = 1; break;
  11727. + case 4 : *level = 2; break;
  11728. + case 2 : *level = 9; break;
  11729. + }
  11730. + }
  11731. +
  11732. + if ((s->cur_file_info.compression_method!=0) &&
  11733. +/* #ifdef HAVE_BZIP2 */
  11734. + (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
  11735. +/* #endif */
  11736. + (s->cur_file_info.compression_method!=Z_DEFLATED))
  11737. +
  11738. + err=UNZ_BADZIPFILE;
  11739. +
  11740. + pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
  11741. + pfile_in_zip_read_info->crc32=0;
  11742. + pfile_in_zip_read_info->total_out_64=0;
  11743. + pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method;
  11744. + pfile_in_zip_read_info->filestream=s->filestream;
  11745. + pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
  11746. + pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
  11747. +
  11748. + pfile_in_zip_read_info->stream.total_out = 0;
  11749. +
  11750. + if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw))
  11751. + {
  11752. +#ifdef HAVE_BZIP2
  11753. + pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0;
  11754. + pfile_in_zip_read_info->bstream.bzfree = (free_func)0;
  11755. + pfile_in_zip_read_info->bstream.opaque = (voidpf)0;
  11756. + pfile_in_zip_read_info->bstream.state = (voidpf)0;
  11757. +
  11758. + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
  11759. + pfile_in_zip_read_info->stream.zfree = (free_func)0;
  11760. + pfile_in_zip_read_info->stream.opaque = (voidpf)0;
  11761. + pfile_in_zip_read_info->stream.next_in = (voidpf)0;
  11762. + pfile_in_zip_read_info->stream.avail_in = 0;
  11763. +
  11764. + err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0);
  11765. + if (err == Z_OK)
  11766. + pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED;
  11767. + else
  11768. + {
  11769. + TRYFREE(pfile_in_zip_read_info);
  11770. + return err;
  11771. + }
  11772. +#else
  11773. + pfile_in_zip_read_info->raw=1;
  11774. +#endif
  11775. + }
  11776. + else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw))
  11777. + {
  11778. + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
  11779. + pfile_in_zip_read_info->stream.zfree = (free_func)0;
  11780. + pfile_in_zip_read_info->stream.opaque = (voidpf)0;
  11781. + pfile_in_zip_read_info->stream.next_in = 0;
  11782. + pfile_in_zip_read_info->stream.avail_in = 0;
  11783. +
  11784. + err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
  11785. + if (err == Z_OK)
  11786. + pfile_in_zip_read_info->stream_initialised=Z_DEFLATED;
  11787. + else
  11788. + {
  11789. + TRYFREE(pfile_in_zip_read_info);
  11790. + return err;
  11791. + }
  11792. + /* windowBits is passed < 0 to tell that there is no zlib header.
  11793. + * Note that in this case inflate *requires* an extra "dummy" byte
  11794. + * after the compressed stream in order to complete decompression and
  11795. + * return Z_STREAM_END.
  11796. + * In unzip, i don't wait absolutely Z_STREAM_END because I known the
  11797. + * size of both compressed and uncompressed data
  11798. + */
  11799. + }
  11800. + pfile_in_zip_read_info->rest_read_compressed =
  11801. + s->cur_file_info.compressed_size ;
  11802. + pfile_in_zip_read_info->rest_read_uncompressed =
  11803. + s->cur_file_info.uncompressed_size ;
  11804. +
  11805. +
  11806. + pfile_in_zip_read_info->pos_in_zipfile =
  11807. + s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
  11808. + iSizeVar;
  11809. +
  11810. + pfile_in_zip_read_info->stream.avail_in = (uInt)0;
  11811. +
  11812. + s->pfile_in_zip_read = pfile_in_zip_read_info;
  11813. + s->encrypted = 0;
  11814. +
  11815. +# ifndef NOUNCRYPT
  11816. + if (password != NULL)
  11817. + {
  11818. + int i;
  11819. + s->pcrc_32_tab = get_crc_table();
  11820. + init_keys(password,s->keys,s->pcrc_32_tab);
  11821. + if (ZSEEK64(s->z_filefunc, s->filestream,
  11822. + s->pfile_in_zip_read->pos_in_zipfile +
  11823. + s->pfile_in_zip_read->byte_before_the_zipfile,
  11824. + SEEK_SET)!=0)
  11825. + return UNZ_INTERNALERROR;
  11826. + if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12)
  11827. + return UNZ_INTERNALERROR;
  11828. +
  11829. + for (i = 0; i<12; i++)
  11830. + zdecode(s->keys,s->pcrc_32_tab,source[i]);
  11831. +
  11832. + s->pfile_in_zip_read->pos_in_zipfile+=12;
  11833. + s->encrypted=1;
  11834. + }
  11835. +# endif
  11836. +
  11837. +
  11838. + return UNZ_OK;
  11839. +}
  11840. +
  11841. +extern int ZEXPORT unzOpenCurrentFile (unzFile file)
  11842. +{
  11843. + return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
  11844. +}
  11845. +
  11846. +extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char* password)
  11847. +{
  11848. + return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
  11849. +}
  11850. +
  11851. +extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw)
  11852. +{
  11853. + return unzOpenCurrentFile3(file, method, level, raw, NULL);
  11854. +}
  11855. +
  11856. +/** Addition for GDAL : START */
  11857. +
  11858. +extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file)
  11859. +{
  11860. + unz64_s* s;
  11861. + file_in_zip64_read_info_s* pfile_in_zip_read_info;
  11862. + s=(unz64_s*)file;
  11863. + if (file==NULL)
  11864. + return 0; //UNZ_PARAMERROR;
  11865. + pfile_in_zip_read_info=s->pfile_in_zip_read;
  11866. + if (pfile_in_zip_read_info==NULL)
  11867. + return 0; //UNZ_PARAMERROR;
  11868. + return pfile_in_zip_read_info->pos_in_zipfile +
  11869. + pfile_in_zip_read_info->byte_before_the_zipfile;
  11870. +}
  11871. +
  11872. +/** Addition for GDAL : END */
  11873. +
  11874. +/*
  11875. + Read bytes from the current file.
  11876. + buf contain buffer where data must be copied
  11877. + len the size of buf.
  11878. +
  11879. + return the number of byte copied if somes bytes are copied
  11880. + return 0 if the end of file was reached
  11881. + return <0 with error code if there is an error
  11882. + (UNZ_ERRNO for IO error, or zLib error for uncompress error)
  11883. +*/
  11884. +extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len)
  11885. +{
  11886. + int err=UNZ_OK;
  11887. + uInt iRead = 0;
  11888. + unz64_s* s;
  11889. + file_in_zip64_read_info_s* pfile_in_zip_read_info;
  11890. + if (file==NULL)
  11891. + return UNZ_PARAMERROR;
  11892. + s=(unz64_s*)file;
  11893. + pfile_in_zip_read_info=s->pfile_in_zip_read;
  11894. +
  11895. + if (pfile_in_zip_read_info==NULL)
  11896. + return UNZ_PARAMERROR;
  11897. +
  11898. +
  11899. + if ((pfile_in_zip_read_info->read_buffer == NULL))
  11900. + return UNZ_END_OF_LIST_OF_FILE;
  11901. + if (len==0)
  11902. + return 0;
  11903. +
  11904. + pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
  11905. +
  11906. + pfile_in_zip_read_info->stream.avail_out = (uInt)len;
  11907. +
  11908. + if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
  11909. + (!(pfile_in_zip_read_info->raw)))
  11910. + pfile_in_zip_read_info->stream.avail_out =
  11911. + (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
  11912. +
  11913. + if ((len>pfile_in_zip_read_info->rest_read_compressed+
  11914. + pfile_in_zip_read_info->stream.avail_in) &&
  11915. + (pfile_in_zip_read_info->raw))
  11916. + pfile_in_zip_read_info->stream.avail_out =
  11917. + (uInt)pfile_in_zip_read_info->rest_read_compressed+
  11918. + pfile_in_zip_read_info->stream.avail_in;
  11919. +
  11920. + while (pfile_in_zip_read_info->stream.avail_out>0)
  11921. + {
  11922. + if ((pfile_in_zip_read_info->stream.avail_in==0) &&
  11923. + (pfile_in_zip_read_info->rest_read_compressed>0))
  11924. + {
  11925. + uInt uReadThis = UNZ_BUFSIZE;
  11926. + if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
  11927. + uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
  11928. + if (uReadThis == 0)
  11929. + return UNZ_EOF;
  11930. + if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
  11931. + pfile_in_zip_read_info->filestream,
  11932. + pfile_in_zip_read_info->pos_in_zipfile +
  11933. + pfile_in_zip_read_info->byte_before_the_zipfile,
  11934. + ZLIB_FILEFUNC_SEEK_SET)!=0)
  11935. + return UNZ_ERRNO;
  11936. + if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
  11937. + pfile_in_zip_read_info->filestream,
  11938. + pfile_in_zip_read_info->read_buffer,
  11939. + uReadThis)!=uReadThis)
  11940. + return UNZ_ERRNO;
  11941. +
  11942. +
  11943. +# ifndef NOUNCRYPT
  11944. + if(s->encrypted)
  11945. + {
  11946. + uInt i;
  11947. + for(i=0;i<uReadThis;i++)
  11948. + pfile_in_zip_read_info->read_buffer[i] =
  11949. + zdecode(s->keys,s->pcrc_32_tab,
  11950. + pfile_in_zip_read_info->read_buffer[i]);
  11951. + }
  11952. +# endif
  11953. +
  11954. +
  11955. + pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
  11956. +
  11957. + pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
  11958. +
  11959. + pfile_in_zip_read_info->stream.next_in =
  11960. + (Bytef*)pfile_in_zip_read_info->read_buffer;
  11961. + pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
  11962. + }
  11963. +
  11964. + if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
  11965. + {
  11966. + uInt uDoCopy,i ;
  11967. +
  11968. + if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
  11969. + (pfile_in_zip_read_info->rest_read_compressed == 0))
  11970. + return (iRead==0) ? UNZ_EOF : iRead;
  11971. +
  11972. + if (pfile_in_zip_read_info->stream.avail_out <
  11973. + pfile_in_zip_read_info->stream.avail_in)
  11974. + uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
  11975. + else
  11976. + uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
  11977. +
  11978. + for (i=0;i<uDoCopy;i++)
  11979. + *(pfile_in_zip_read_info->stream.next_out+i) =
  11980. + *(pfile_in_zip_read_info->stream.next_in+i);
  11981. +
  11982. + pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy;
  11983. +
  11984. + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
  11985. + pfile_in_zip_read_info->stream.next_out,
  11986. + uDoCopy);
  11987. + pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
  11988. + pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
  11989. + pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
  11990. + pfile_in_zip_read_info->stream.next_out += uDoCopy;
  11991. + pfile_in_zip_read_info->stream.next_in += uDoCopy;
  11992. + pfile_in_zip_read_info->stream.total_out += uDoCopy;
  11993. + iRead += uDoCopy;
  11994. + }
  11995. + else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED)
  11996. + {
  11997. +#ifdef HAVE_BZIP2
  11998. + uLong uTotalOutBefore,uTotalOutAfter;
  11999. + const Bytef *bufBefore;
  12000. + uLong uOutThis;
  12001. +
  12002. + pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in;
  12003. + pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in;
  12004. + pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in;
  12005. + pfile_in_zip_read_info->bstream.total_in_hi32 = 0;
  12006. + pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip_read_info->stream.next_out;
  12007. + pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out;
  12008. + pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out;
  12009. + pfile_in_zip_read_info->bstream.total_out_hi32 = 0;
  12010. +
  12011. + uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32;
  12012. + bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out;
  12013. +
  12014. + err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream);
  12015. +
  12016. + uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32;
  12017. + uOutThis = uTotalOutAfter-uTotalOutBefore;
  12018. +
  12019. + pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
  12020. +
  12021. + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis));
  12022. + pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis;
  12023. + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
  12024. +
  12025. + pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in;
  12026. + pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in;
  12027. + pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32;
  12028. + pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read_info->bstream.next_out;
  12029. + pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out;
  12030. + pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32;
  12031. +
  12032. + if (err==BZ_STREAM_END)
  12033. + return (iRead==0) ? UNZ_EOF : iRead;
  12034. + if (err!=BZ_OK)
  12035. + break;
  12036. +#endif
  12037. + } // end Z_BZIP2ED
  12038. + else
  12039. + {
  12040. + ZPOS64_T uTotalOutBefore,uTotalOutAfter;
  12041. + const Bytef *bufBefore;
  12042. + ZPOS64_T uOutThis;
  12043. + int flush=Z_SYNC_FLUSH;
  12044. +
  12045. + uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
  12046. + bufBefore = pfile_in_zip_read_info->stream.next_out;
  12047. +
  12048. + /*
  12049. + if ((pfile_in_zip_read_info->rest_read_uncompressed ==
  12050. + pfile_in_zip_read_info->stream.avail_out) &&
  12051. + (pfile_in_zip_read_info->rest_read_compressed == 0))
  12052. + flush = Z_FINISH;
  12053. + */
  12054. + err=inflate(&pfile_in_zip_read_info->stream,flush);
  12055. +
  12056. + if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
  12057. + err = Z_DATA_ERROR;
  12058. +
  12059. + uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
  12060. + uOutThis = uTotalOutAfter-uTotalOutBefore;
  12061. +
  12062. + pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
  12063. +
  12064. + pfile_in_zip_read_info->crc32 =
  12065. + crc32(pfile_in_zip_read_info->crc32,bufBefore,
  12066. + (uInt)(uOutThis));
  12067. +
  12068. + pfile_in_zip_read_info->rest_read_uncompressed -=
  12069. + uOutThis;
  12070. +
  12071. + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
  12072. +
  12073. + if (err==Z_STREAM_END)
  12074. + return (iRead==0) ? UNZ_EOF : iRead;
  12075. + if (err!=Z_OK)
  12076. + break;
  12077. + }
  12078. + }
  12079. +
  12080. + if (err==Z_OK)
  12081. + return iRead;
  12082. + return err;
  12083. +}
  12084. +
  12085. +
  12086. +/*
  12087. + Give the current position in uncompressed data
  12088. +*/
  12089. +extern z_off_t ZEXPORT unztell (unzFile file)
  12090. +{
  12091. + unz64_s* s;
  12092. + file_in_zip64_read_info_s* pfile_in_zip_read_info;
  12093. + if (file==NULL)
  12094. + return UNZ_PARAMERROR;
  12095. + s=(unz64_s*)file;
  12096. + pfile_in_zip_read_info=s->pfile_in_zip_read;
  12097. +
  12098. + if (pfile_in_zip_read_info==NULL)
  12099. + return UNZ_PARAMERROR;
  12100. +
  12101. + return (z_off_t)pfile_in_zip_read_info->stream.total_out;
  12102. +}
  12103. +
  12104. +extern ZPOS64_T ZEXPORT unztell64 (unzFile file)
  12105. +{
  12106. +
  12107. + unz64_s* s;
  12108. + file_in_zip64_read_info_s* pfile_in_zip_read_info;
  12109. + if (file==NULL)
  12110. + return (ZPOS64_T)-1;
  12111. + s=(unz64_s*)file;
  12112. + pfile_in_zip_read_info=s->pfile_in_zip_read;
  12113. +
  12114. + if (pfile_in_zip_read_info==NULL)
  12115. + return (ZPOS64_T)-1;
  12116. +
  12117. + return pfile_in_zip_read_info->total_out_64;
  12118. +}
  12119. +
  12120. +
  12121. +/*
  12122. + return 1 if the end of file was reached, 0 elsewhere
  12123. +*/
  12124. +extern int ZEXPORT unzeof (unzFile file)
  12125. +{
  12126. + unz64_s* s;
  12127. + file_in_zip64_read_info_s* pfile_in_zip_read_info;
  12128. + if (file==NULL)
  12129. + return UNZ_PARAMERROR;
  12130. + s=(unz64_s*)file;
  12131. + pfile_in_zip_read_info=s->pfile_in_zip_read;
  12132. +
  12133. + if (pfile_in_zip_read_info==NULL)
  12134. + return UNZ_PARAMERROR;
  12135. +
  12136. + if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
  12137. + return 1;
  12138. + else
  12139. + return 0;
  12140. +}
  12141. +
  12142. +
  12143. +
  12144. +/*
  12145. +Read extra field from the current file (opened by unzOpenCurrentFile)
  12146. +This is the local-header version of the extra field (sometimes, there is
  12147. +more info in the local-header version than in the central-header)
  12148. +
  12149. + if buf==NULL, it return the size of the local extra field that can be read
  12150. +
  12151. + if buf!=NULL, len is the size of the buffer, the extra header is copied in
  12152. + buf.
  12153. + the return value is the number of bytes copied in buf, or (if <0)
  12154. + the error code
  12155. +*/
  12156. +extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len)
  12157. +{
  12158. + unz64_s* s;
  12159. + file_in_zip64_read_info_s* pfile_in_zip_read_info;
  12160. + uInt read_now;
  12161. + ZPOS64_T size_to_read;
  12162. +
  12163. + if (file==NULL)
  12164. + return UNZ_PARAMERROR;
  12165. + s=(unz64_s*)file;
  12166. + pfile_in_zip_read_info=s->pfile_in_zip_read;
  12167. +
  12168. + if (pfile_in_zip_read_info==NULL)
  12169. + return UNZ_PARAMERROR;
  12170. +
  12171. + size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
  12172. + pfile_in_zip_read_info->pos_local_extrafield);
  12173. +
  12174. + if (buf==NULL)
  12175. + return (int)size_to_read;
  12176. +
  12177. + if (len>size_to_read)
  12178. + read_now = (uInt)size_to_read;
  12179. + else
  12180. + read_now = (uInt)len ;
  12181. +
  12182. + if (read_now==0)
  12183. + return 0;
  12184. +
  12185. + if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
  12186. + pfile_in_zip_read_info->filestream,
  12187. + pfile_in_zip_read_info->offset_local_extrafield +
  12188. + pfile_in_zip_read_info->pos_local_extrafield,
  12189. + ZLIB_FILEFUNC_SEEK_SET)!=0)
  12190. + return UNZ_ERRNO;
  12191. +
  12192. + if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
  12193. + pfile_in_zip_read_info->filestream,
  12194. + buf,read_now)!=read_now)
  12195. + return UNZ_ERRNO;
  12196. +
  12197. + return (int)read_now;
  12198. +}
  12199. +
  12200. +/*
  12201. + Close the file in zip opened with unzipOpenCurrentFile
  12202. + Return UNZ_CRCERROR if all the file was read but the CRC is not good
  12203. +*/
  12204. +extern int ZEXPORT unzCloseCurrentFile (unzFile file)
  12205. +{
  12206. + int err=UNZ_OK;
  12207. +
  12208. + unz64_s* s;
  12209. + file_in_zip64_read_info_s* pfile_in_zip_read_info;
  12210. + if (file==NULL)
  12211. + return UNZ_PARAMERROR;
  12212. + s=(unz64_s*)file;
  12213. + pfile_in_zip_read_info=s->pfile_in_zip_read;
  12214. +
  12215. + if (pfile_in_zip_read_info==NULL)
  12216. + return UNZ_PARAMERROR;
  12217. +
  12218. +
  12219. + if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
  12220. + (!pfile_in_zip_read_info->raw))
  12221. + {
  12222. + if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
  12223. + err=UNZ_CRCERROR;
  12224. + }
  12225. +
  12226. +
  12227. + TRYFREE(pfile_in_zip_read_info->read_buffer);
  12228. + pfile_in_zip_read_info->read_buffer = NULL;
  12229. + if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED)
  12230. + inflateEnd(&pfile_in_zip_read_info->stream);
  12231. +#ifdef HAVE_BZIP2
  12232. + else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED)
  12233. + BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream);
  12234. +#endif
  12235. +
  12236. +
  12237. + pfile_in_zip_read_info->stream_initialised = 0;
  12238. + TRYFREE(pfile_in_zip_read_info);
  12239. +
  12240. + s->pfile_in_zip_read=NULL;
  12241. +
  12242. + return err;
  12243. +}
  12244. +
  12245. +
  12246. +/*
  12247. + Get the global comment string of the ZipFile, in the szComment buffer.
  12248. + uSizeBuf is the size of the szComment buffer.
  12249. + return the number of byte copied or an error code <0
  12250. +*/
  12251. +extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf)
  12252. +{
  12253. + unz64_s* s;
  12254. + uLong uReadThis ;
  12255. + if (file==NULL)
  12256. + return (int)UNZ_PARAMERROR;
  12257. + s=(unz64_s*)file;
  12258. +
  12259. + uReadThis = uSizeBuf;
  12260. + if (uReadThis>s->gi.size_comment)
  12261. + uReadThis = s->gi.size_comment;
  12262. +
  12263. + if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
  12264. + return UNZ_ERRNO;
  12265. +
  12266. + if (uReadThis>0)
  12267. + {
  12268. + *szComment='\0';
  12269. + if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
  12270. + return UNZ_ERRNO;
  12271. + }
  12272. +
  12273. + if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
  12274. + *(szComment+s->gi.size_comment)='\0';
  12275. + return (int)uReadThis;
  12276. +}
  12277. +
  12278. +/* Additions by RX '2004 */
  12279. +extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file)
  12280. +{
  12281. + unz64_s* s;
  12282. +
  12283. + if (file==NULL)
  12284. + return 0; //UNZ_PARAMERROR;
  12285. + s=(unz64_s*)file;
  12286. + if (!s->current_file_ok)
  12287. + return 0;
  12288. + if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
  12289. + if (s->num_file==s->gi.number_entry)
  12290. + return 0;
  12291. + return s->pos_in_central_dir;
  12292. +}
  12293. +
  12294. +extern uLong ZEXPORT unzGetOffset (unzFile file)
  12295. +{
  12296. + ZPOS64_T offset64;
  12297. +
  12298. + if (file==NULL)
  12299. + return 0; //UNZ_PARAMERROR;
  12300. + offset64 = unzGetOffset64(file);
  12301. + return (uLong)offset64;
  12302. +}
  12303. +
  12304. +extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos)
  12305. +{
  12306. + unz64_s* s;
  12307. + int err;
  12308. +
  12309. + if (file==NULL)
  12310. + return UNZ_PARAMERROR;
  12311. + s=(unz64_s*)file;
  12312. +
  12313. + s->pos_in_central_dir = pos;
  12314. + s->num_file = s->gi.number_entry; /* hack */
  12315. + err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
  12316. + &s->cur_file_info_internal,
  12317. + NULL,0,NULL,0,NULL,0);
  12318. + s->current_file_ok = (err == UNZ_OK);
  12319. + return err;
  12320. +}
  12321. +
  12322. +extern int ZEXPORT unzSetOffset (unzFile file, uLong pos)
  12323. +{
  12324. + return unzSetOffset64(file,pos);
  12325. +}
  12326. Index: src/zip.c
  12327. ===================================================================
  12328. --- src/zip.c (nonexistent)
  12329. +++ src/zip.c (working copy)
  12330. @@ -0,0 +1,2004 @@
  12331. +/* zip.c -- IO on .zip files using zlib
  12332. + Version 1.1, February 14h, 2010
  12333. + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
  12334. +
  12335. + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
  12336. +
  12337. + Modifications for Zip64 support
  12338. + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
  12339. +
  12340. + For more info read MiniZip_info.txt
  12341. +
  12342. + Changes
  12343. + Oct-2009 - Mathias Svensson - Remove old C style function prototypes
  12344. + Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives
  12345. + Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions.
  12346. + Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data
  12347. + It is used when recreting zip archive with RAW when deleting items from a zip.
  12348. + ZIP64 data is automaticly added to items that needs it, and existing ZIP64 data need to be removed.
  12349. + Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required)
  12350. + Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
  12351. +
  12352. +*/
  12353. +
  12354. +
  12355. +#include <stdio.h>
  12356. +#include <stdlib.h>
  12357. +#include <string.h>
  12358. +#include <time.h>
  12359. +#include "zlib.h"
  12360. +#include "zip.h"
  12361. +
  12362. +#ifdef STDC
  12363. +# include <stddef.h>
  12364. +# include <string.h>
  12365. +# include <stdlib.h>
  12366. +#endif
  12367. +#ifdef NO_ERRNO_H
  12368. + extern int errno;
  12369. +#else
  12370. +# include <errno.h>
  12371. +#endif
  12372. +
  12373. +
  12374. +#ifndef local
  12375. +# define local static
  12376. +#endif
  12377. +/* compile with -Dlocal if your debugger can't find static symbols */
  12378. +
  12379. +#ifndef VERSIONMADEBY
  12380. +# define VERSIONMADEBY (0x0) /* platform depedent */
  12381. +#endif
  12382. +
  12383. +#ifndef Z_BUFSIZE
  12384. +#define Z_BUFSIZE (64*1024) //(16384)
  12385. +#endif
  12386. +
  12387. +#ifndef Z_MAXFILENAMEINZIP
  12388. +#define Z_MAXFILENAMEINZIP (256)
  12389. +#endif
  12390. +
  12391. +#ifndef ALLOC
  12392. +# define ALLOC(size) (malloc(size))
  12393. +#endif
  12394. +#ifndef TRYFREE
  12395. +# define TRYFREE(p) {if (p) free(p);}
  12396. +#endif
  12397. +
  12398. +/*
  12399. +#define SIZECENTRALDIRITEM (0x2e)
  12400. +#define SIZEZIPLOCALHEADER (0x1e)
  12401. +*/
  12402. +
  12403. +/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
  12404. +
  12405. +
  12406. +// NOT sure that this work on ALL platform
  12407. +#define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32))
  12408. +
  12409. +#ifndef SEEK_CUR
  12410. +#define SEEK_CUR 1
  12411. +#endif
  12412. +
  12413. +#ifndef SEEK_END
  12414. +#define SEEK_END 2
  12415. +#endif
  12416. +
  12417. +#ifndef SEEK_SET
  12418. +#define SEEK_SET 0
  12419. +#endif
  12420. +
  12421. +#ifndef DEF_MEM_LEVEL
  12422. +#if MAX_MEM_LEVEL >= 8
  12423. +# define DEF_MEM_LEVEL 8
  12424. +#else
  12425. +# define DEF_MEM_LEVEL MAX_MEM_LEVEL
  12426. +#endif
  12427. +#endif
  12428. +const char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
  12429. +
  12430. +
  12431. +#define SIZEDATA_INDATABLOCK (4096-(4*4))
  12432. +
  12433. +#define LOCALHEADERMAGIC (0x04034b50)
  12434. +#define CENTRALHEADERMAGIC (0x02014b50)
  12435. +#define ENDHEADERMAGIC (0x06054b50)
  12436. +#define ZIP64ENDHEADERMAGIC (0x6064b50)
  12437. +#define ZIP64ENDLOCHEADERMAGIC (0x7064b50)
  12438. +
  12439. +#define FLAG_LOCALHEADER_OFFSET (0x06)
  12440. +#define CRC_LOCALHEADER_OFFSET (0x0e)
  12441. +
  12442. +#define SIZECENTRALHEADER (0x2e) /* 46 */
  12443. +
  12444. +typedef struct linkedlist_datablock_internal_s
  12445. +{
  12446. + struct linkedlist_datablock_internal_s* next_datablock;
  12447. + uLong avail_in_this_block;
  12448. + uLong filled_in_this_block;
  12449. + uLong unused; /* for future use and alignement */
  12450. + unsigned char data[SIZEDATA_INDATABLOCK];
  12451. +} linkedlist_datablock_internal;
  12452. +
  12453. +typedef struct linkedlist_data_s
  12454. +{
  12455. + linkedlist_datablock_internal* first_block;
  12456. + linkedlist_datablock_internal* last_block;
  12457. +} linkedlist_data;
  12458. +
  12459. +
  12460. +typedef struct
  12461. +{
  12462. + z_stream stream; /* zLib stream structure for inflate */
  12463. +#ifdef HAVE_BZIP2
  12464. + bz_stream bstream; /* bzLib stream structure for bziped */
  12465. +#endif
  12466. +
  12467. + int stream_initialised; /* 1 is stream is initialised */
  12468. + uInt pos_in_buffered_data; /* last written byte in buffered_data */
  12469. +
  12470. + ZPOS64_T pos_local_header; /* offset of the local header of the file
  12471. + currenty writing */
  12472. + char* central_header; /* central header data for the current file */
  12473. + uLong size_centralExtra;
  12474. + uLong size_centralheader; /* size of the central header for cur file */
  12475. + uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */
  12476. + uLong flag; /* flag of the file currently writing */
  12477. +
  12478. + int method; /* compression method of file currenty wr.*/
  12479. + int raw; /* 1 for directly writing raw data */
  12480. + Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
  12481. + uLong dosDate;
  12482. + uLong crc32;
  12483. + int encrypt;
  12484. + int zip64; /* Add ZIP64 extened information in the extra field */
  12485. + ZPOS64_T pos_zip64extrainfo;
  12486. + ZPOS64_T totalCompressedData;
  12487. + ZPOS64_T totalUncompressedData;
  12488. +#ifndef NOCRYPT
  12489. + unsigned long keys[3]; /* keys defining the pseudo-random sequence */
  12490. + const unsigned long* pcrc_32_tab;
  12491. + int crypt_header_size;
  12492. +#endif
  12493. +} curfile64_info;
  12494. +
  12495. +typedef struct
  12496. +{
  12497. + zlib_filefunc64_32_def z_filefunc;
  12498. + voidpf filestream; /* io structore of the zipfile */
  12499. + linkedlist_data central_dir;/* datablock with central dir in construction*/
  12500. + int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/
  12501. + curfile64_info ci; /* info on the file curretly writing */
  12502. +
  12503. + ZPOS64_T begin_pos; /* position of the beginning of the zipfile */
  12504. + ZPOS64_T add_position_when_writting_offset;
  12505. + ZPOS64_T number_entry;
  12506. +
  12507. +#ifndef NO_ADDFILEINEXISTINGZIP
  12508. + char *globalcomment;
  12509. +#endif
  12510. +
  12511. +} zip64_internal;
  12512. +
  12513. +
  12514. +#ifndef NOCRYPT
  12515. +#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
  12516. +#include "crypt.h"
  12517. +#endif
  12518. +
  12519. +local linkedlist_datablock_internal* allocate_new_datablock()
  12520. +{
  12521. + linkedlist_datablock_internal* ldi;
  12522. + ldi = (linkedlist_datablock_internal*)
  12523. + ALLOC(sizeof(linkedlist_datablock_internal));
  12524. + if (ldi!=NULL)
  12525. + {
  12526. + ldi->next_datablock = NULL ;
  12527. + ldi->filled_in_this_block = 0 ;
  12528. + ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
  12529. + }
  12530. + return ldi;
  12531. +}
  12532. +
  12533. +local void free_datablock(linkedlist_datablock_internal* ldi)
  12534. +{
  12535. + while (ldi!=NULL)
  12536. + {
  12537. + linkedlist_datablock_internal* ldinext = ldi->next_datablock;
  12538. + TRYFREE(ldi);
  12539. + ldi = ldinext;
  12540. + }
  12541. +}
  12542. +
  12543. +local void init_linkedlist(linkedlist_data* ll)
  12544. +{
  12545. + ll->first_block = ll->last_block = NULL;
  12546. +}
  12547. +
  12548. +local void free_linkedlist(linkedlist_data* ll)
  12549. +{
  12550. + free_datablock(ll->first_block);
  12551. + ll->first_block = ll->last_block = NULL;
  12552. +}
  12553. +
  12554. +
  12555. +local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len)
  12556. +{
  12557. + linkedlist_datablock_internal* ldi;
  12558. + const unsigned char* from_copy;
  12559. +
  12560. + if (ll==NULL)
  12561. + return ZIP_INTERNALERROR;
  12562. +
  12563. + if (ll->last_block == NULL)
  12564. + {
  12565. + ll->first_block = ll->last_block = allocate_new_datablock();
  12566. + if (ll->first_block == NULL)
  12567. + return ZIP_INTERNALERROR;
  12568. + }
  12569. +
  12570. + ldi = ll->last_block;
  12571. + from_copy = (unsigned char*)buf;
  12572. +
  12573. + while (len>0)
  12574. + {
  12575. + uInt copy_this;
  12576. + uInt i;
  12577. + unsigned char* to_copy;
  12578. +
  12579. + if (ldi->avail_in_this_block==0)
  12580. + {
  12581. + ldi->next_datablock = allocate_new_datablock();
  12582. + if (ldi->next_datablock == NULL)
  12583. + return ZIP_INTERNALERROR;
  12584. + ldi = ldi->next_datablock ;
  12585. + ll->last_block = ldi;
  12586. + }
  12587. +
  12588. + if (ldi->avail_in_this_block < len)
  12589. + copy_this = (uInt)ldi->avail_in_this_block;
  12590. + else
  12591. + copy_this = (uInt)len;
  12592. +
  12593. + to_copy = &(ldi->data[ldi->filled_in_this_block]);
  12594. +
  12595. + for (i=0;i<copy_this;i++)
  12596. + *(to_copy+i)=*(from_copy+i);
  12597. +
  12598. + ldi->filled_in_this_block += copy_this;
  12599. + ldi->avail_in_this_block -= copy_this;
  12600. + from_copy += copy_this ;
  12601. + len -= copy_this;
  12602. + }
  12603. + return ZIP_OK;
  12604. +}
  12605. +
  12606. +
  12607. +
  12608. +/****************************************************************************/
  12609. +
  12610. +#ifndef NO_ADDFILEINEXISTINGZIP
  12611. +/* ===========================================================================
  12612. + Inputs a long in LSB order to the given file
  12613. + nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T)
  12614. +*/
  12615. +
  12616. +local int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte));
  12617. +local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)
  12618. +{
  12619. + unsigned char buf[8];
  12620. + int n;
  12621. + for (n = 0; n < nbByte; n++)
  12622. + {
  12623. + buf[n] = (unsigned char)(x & 0xff);
  12624. + x >>= 8;
  12625. + }
  12626. + if (x != 0)
  12627. + { /* data overflow - hack for ZIP64 (X Roche) */
  12628. + for (n = 0; n < nbByte; n++)
  12629. + {
  12630. + buf[n] = 0xff;
  12631. + }
  12632. + }
  12633. +
  12634. + if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte)
  12635. + return ZIP_ERRNO;
  12636. + else
  12637. + return ZIP_OK;
  12638. +}
  12639. +
  12640. +local void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte));
  12641. +local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte)
  12642. +{
  12643. + unsigned char* buf=(unsigned char*)dest;
  12644. + int n;
  12645. + for (n = 0; n < nbByte; n++) {
  12646. + buf[n] = (unsigned char)(x & 0xff);
  12647. + x >>= 8;
  12648. + }
  12649. +
  12650. + if (x != 0)
  12651. + { /* data overflow - hack for ZIP64 */
  12652. + for (n = 0; n < nbByte; n++)
  12653. + {
  12654. + buf[n] = 0xff;
  12655. + }
  12656. + }
  12657. +}
  12658. +
  12659. +/****************************************************************************/
  12660. +
  12661. +
  12662. +local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm)
  12663. +{
  12664. + uLong year = (uLong)ptm->tm_year;
  12665. + if (year>=1980)
  12666. + year-=1980;
  12667. + else if (year>=80)
  12668. + year-=80;
  12669. + return
  12670. + (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |
  12671. + ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
  12672. +}
  12673. +
  12674. +
  12675. +/****************************************************************************/
  12676. +
  12677. +local int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi));
  12678. +
  12679. +local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi)
  12680. +{
  12681. + unsigned char c;
  12682. + int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
  12683. + if (err==1)
  12684. + {
  12685. + *pi = (int)c;
  12686. + return ZIP_OK;
  12687. + }
  12688. + else
  12689. + {
  12690. + if (ZERROR64(*pzlib_filefunc_def,filestream))
  12691. + return ZIP_ERRNO;
  12692. + else
  12693. + return ZIP_EOF;
  12694. + }
  12695. +}
  12696. +
  12697. +
  12698. +/* ===========================================================================
  12699. + Reads a long in LSB order from the given gz_stream. Sets
  12700. +*/
  12701. +local int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
  12702. +
  12703. +local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
  12704. +{
  12705. + uLong x ;
  12706. + int i = 0;
  12707. + int err;
  12708. +
  12709. + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
  12710. + x = (uLong)i;
  12711. +
  12712. + if (err==ZIP_OK)
  12713. + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
  12714. + x += ((uLong)i)<<8;
  12715. +
  12716. + if (err==ZIP_OK)
  12717. + *pX = x;
  12718. + else
  12719. + *pX = 0;
  12720. + return err;
  12721. +}
  12722. +
  12723. +local int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
  12724. +
  12725. +local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
  12726. +{
  12727. + uLong x ;
  12728. + int i = 0;
  12729. + int err;
  12730. +
  12731. + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
  12732. + x = (uLong)i;
  12733. +
  12734. + if (err==ZIP_OK)
  12735. + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
  12736. + x += ((uLong)i)<<8;
  12737. +
  12738. + if (err==ZIP_OK)
  12739. + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
  12740. + x += ((uLong)i)<<16;
  12741. +
  12742. + if (err==ZIP_OK)
  12743. + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
  12744. + x += ((uLong)i)<<24;
  12745. +
  12746. + if (err==ZIP_OK)
  12747. + *pX = x;
  12748. + else
  12749. + *pX = 0;
  12750. + return err;
  12751. +}
  12752. +
  12753. +local int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX));
  12754. +
  12755. +
  12756. +local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)
  12757. +{
  12758. + ZPOS64_T x;
  12759. + int i = 0;
  12760. + int err;
  12761. +
  12762. + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
  12763. + x = (ZPOS64_T)i;
  12764. +
  12765. + if (err==ZIP_OK)
  12766. + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
  12767. + x += ((ZPOS64_T)i)<<8;
  12768. +
  12769. + if (err==ZIP_OK)
  12770. + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
  12771. + x += ((ZPOS64_T)i)<<16;
  12772. +
  12773. + if (err==ZIP_OK)
  12774. + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
  12775. + x += ((ZPOS64_T)i)<<24;
  12776. +
  12777. + if (err==ZIP_OK)
  12778. + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
  12779. + x += ((ZPOS64_T)i)<<32;
  12780. +
  12781. + if (err==ZIP_OK)
  12782. + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
  12783. + x += ((ZPOS64_T)i)<<40;
  12784. +
  12785. + if (err==ZIP_OK)
  12786. + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
  12787. + x += ((ZPOS64_T)i)<<48;
  12788. +
  12789. + if (err==ZIP_OK)
  12790. + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
  12791. + x += ((ZPOS64_T)i)<<56;
  12792. +
  12793. + if (err==ZIP_OK)
  12794. + *pX = x;
  12795. + else
  12796. + *pX = 0;
  12797. +
  12798. + return err;
  12799. +}
  12800. +
  12801. +#ifndef BUFREADCOMMENT
  12802. +#define BUFREADCOMMENT (0x400)
  12803. +#endif
  12804. +/*
  12805. + Locate the Central directory of a zipfile (at the end, just before
  12806. + the global comment)
  12807. +*/
  12808. +local ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
  12809. +
  12810. +local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
  12811. +{
  12812. + unsigned char* buf;
  12813. + ZPOS64_T uSizeFile;
  12814. + ZPOS64_T uBackRead;
  12815. + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
  12816. + ZPOS64_T uPosFound=0;
  12817. +
  12818. + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
  12819. + return 0;
  12820. +
  12821. +
  12822. + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
  12823. +
  12824. + if (uMaxBack>uSizeFile)
  12825. + uMaxBack = uSizeFile;
  12826. +
  12827. + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
  12828. + if (buf==NULL)
  12829. + return 0;
  12830. +
  12831. + uBackRead = 4;
  12832. + while (uBackRead<uMaxBack)
  12833. + {
  12834. + uLong uReadSize;
  12835. + ZPOS64_T uReadPos ;
  12836. + int i;
  12837. + if (uBackRead+BUFREADCOMMENT>uMaxBack)
  12838. + uBackRead = uMaxBack;
  12839. + else
  12840. + uBackRead+=BUFREADCOMMENT;
  12841. + uReadPos = uSizeFile-uBackRead ;
  12842. +
  12843. + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
  12844. + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
  12845. + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
  12846. + break;
  12847. +
  12848. + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
  12849. + break;
  12850. +
  12851. + for (i=(int)uReadSize-3; (i--)>0;)
  12852. + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
  12853. + ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
  12854. + {
  12855. + uPosFound = uReadPos+i;
  12856. + break;
  12857. + }
  12858. +
  12859. + if (uPosFound!=0)
  12860. + break;
  12861. + }
  12862. + TRYFREE(buf);
  12863. + return uPosFound;
  12864. +}
  12865. +
  12866. +/*
  12867. +Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before
  12868. +the global comment)
  12869. +*/
  12870. +local ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
  12871. +
  12872. +local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
  12873. +{
  12874. + unsigned char* buf;
  12875. + ZPOS64_T uSizeFile;
  12876. + ZPOS64_T uBackRead;
  12877. + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
  12878. + ZPOS64_T uPosFound=0;
  12879. + uLong uL;
  12880. + ZPOS64_T relativeOffset;
  12881. +
  12882. + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
  12883. + return 0;
  12884. +
  12885. + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
  12886. +
  12887. + if (uMaxBack>uSizeFile)
  12888. + uMaxBack = uSizeFile;
  12889. +
  12890. + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
  12891. + if (buf==NULL)
  12892. + return 0;
  12893. +
  12894. + uBackRead = 4;
  12895. + while (uBackRead<uMaxBack)
  12896. + {
  12897. + uLong uReadSize;
  12898. + ZPOS64_T uReadPos;
  12899. + int i;
  12900. + if (uBackRead+BUFREADCOMMENT>uMaxBack)
  12901. + uBackRead = uMaxBack;
  12902. + else
  12903. + uBackRead+=BUFREADCOMMENT;
  12904. + uReadPos = uSizeFile-uBackRead ;
  12905. +
  12906. + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
  12907. + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
  12908. + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
  12909. + break;
  12910. +
  12911. + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
  12912. + break;
  12913. +
  12914. + for (i=(int)uReadSize-3; (i--)>0;)
  12915. + {
  12916. + // Signature "0x07064b50" Zip64 end of central directory locater
  12917. + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
  12918. + {
  12919. + uPosFound = uReadPos+i;
  12920. + break;
  12921. + }
  12922. + }
  12923. +
  12924. + if (uPosFound!=0)
  12925. + break;
  12926. + }
  12927. +
  12928. + TRYFREE(buf);
  12929. + if (uPosFound == 0)
  12930. + return 0;
  12931. +
  12932. + /* Zip64 end of central directory locator */
  12933. + if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
  12934. + return 0;
  12935. +
  12936. + /* the signature, already checked */
  12937. + if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
  12938. + return 0;
  12939. +
  12940. + /* number of the disk with the start of the zip64 end of central directory */
  12941. + if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
  12942. + return 0;
  12943. + if (uL != 0)
  12944. + return 0;
  12945. +
  12946. + /* relative offset of the zip64 end of central directory record */
  12947. + if (zip64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=ZIP_OK)
  12948. + return 0;
  12949. +
  12950. + /* total number of disks */
  12951. + if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
  12952. + return 0;
  12953. + if (uL != 1)
  12954. + return 0;
  12955. +
  12956. + /* Goto Zip64 end of central directory record */
  12957. + if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
  12958. + return 0;
  12959. +
  12960. + /* the signature */
  12961. + if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
  12962. + return 0;
  12963. +
  12964. + if (uL != 0x06064b50) // signature of 'Zip64 end of central directory'
  12965. + return 0;
  12966. +
  12967. + return relativeOffset;
  12968. +}
  12969. +
  12970. +int LoadCentralDirectoryRecord(zip64_internal* pziinit)
  12971. +{
  12972. + int err=ZIP_OK;
  12973. + ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
  12974. +
  12975. + ZPOS64_T size_central_dir; /* size of the central directory */
  12976. + ZPOS64_T offset_central_dir; /* offset of start of central directory */
  12977. + ZPOS64_T central_pos;
  12978. + uLong uL;
  12979. +
  12980. + uLong number_disk; /* number of the current dist, used for
  12981. + spaning ZIP, unsupported, always 0*/
  12982. + uLong number_disk_with_CD; /* number the the disk with central dir, used
  12983. + for spaning ZIP, unsupported, always 0*/
  12984. + ZPOS64_T number_entry;
  12985. + ZPOS64_T number_entry_CD; /* total number of entries in
  12986. + the central dir
  12987. + (same than number_entry on nospan) */
  12988. + uLong VersionMadeBy;
  12989. + uLong VersionNeeded;
  12990. + uLong size_comment;
  12991. +
  12992. + int hasZIP64Record = 0;
  12993. +
  12994. + // check first if we find a ZIP64 record
  12995. + central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream);
  12996. + if(central_pos > 0)
  12997. + {
  12998. + hasZIP64Record = 1;
  12999. + }
  13000. + else if(central_pos == 0)
  13001. + {
  13002. + central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream);
  13003. + }
  13004. +
  13005. +/* disable to allow appending to empty ZIP archive
  13006. + if (central_pos==0)
  13007. + err=ZIP_ERRNO;
  13008. +*/
  13009. +
  13010. + if(hasZIP64Record)
  13011. + {
  13012. + ZPOS64_T sizeEndOfCentralDirectory;
  13013. + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)
  13014. + err=ZIP_ERRNO;
  13015. +
  13016. + /* the signature, already checked */
  13017. + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
  13018. + err=ZIP_ERRNO;
  13019. +
  13020. + /* size of zip64 end of central directory record */
  13021. + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory)!=ZIP_OK)
  13022. + err=ZIP_ERRNO;
  13023. +
  13024. + /* version made by */
  13025. + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy)!=ZIP_OK)
  13026. + err=ZIP_ERRNO;
  13027. +
  13028. + /* version needed to extract */
  13029. + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded)!=ZIP_OK)
  13030. + err=ZIP_ERRNO;
  13031. +
  13032. + /* number of this disk */
  13033. + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
  13034. + err=ZIP_ERRNO;
  13035. +
  13036. + /* number of the disk with the start of the central directory */
  13037. + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
  13038. + err=ZIP_ERRNO;
  13039. +
  13040. + /* total number of entries in the central directory on this disk */
  13041. + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry)!=ZIP_OK)
  13042. + err=ZIP_ERRNO;
  13043. +
  13044. + /* total number of entries in the central directory */
  13045. + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&number_entry_CD)!=ZIP_OK)
  13046. + err=ZIP_ERRNO;
  13047. +
  13048. + if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
  13049. + err=ZIP_BADZIPFILE;
  13050. +
  13051. + /* size of the central directory */
  13052. + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&size_central_dir)!=ZIP_OK)
  13053. + err=ZIP_ERRNO;
  13054. +
  13055. + /* offset of start of central directory with respect to the
  13056. + starting disk number */
  13057. + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK)
  13058. + err=ZIP_ERRNO;
  13059. +
  13060. + // TODO..
  13061. + // read the comment from the standard central header.
  13062. + size_comment = 0;
  13063. + }
  13064. + else
  13065. + {
  13066. + // Read End of central Directory info
  13067. + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
  13068. + err=ZIP_ERRNO;
  13069. +
  13070. + /* the signature, already checked */
  13071. + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
  13072. + err=ZIP_ERRNO;
  13073. +
  13074. + /* number of this disk */
  13075. + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
  13076. + err=ZIP_ERRNO;
  13077. +
  13078. + /* number of the disk with the start of the central directory */
  13079. + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
  13080. + err=ZIP_ERRNO;
  13081. +
  13082. + /* total number of entries in the central dir on this disk */
  13083. + number_entry = 0;
  13084. + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
  13085. + err=ZIP_ERRNO;
  13086. + else
  13087. + number_entry = uL;
  13088. +
  13089. + /* total number of entries in the central dir */
  13090. + number_entry_CD = 0;
  13091. + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
  13092. + err=ZIP_ERRNO;
  13093. + else
  13094. + number_entry_CD = uL;
  13095. +
  13096. + if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
  13097. + err=ZIP_BADZIPFILE;
  13098. +
  13099. + /* size of the central directory */
  13100. + size_central_dir = 0;
  13101. + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
  13102. + err=ZIP_ERRNO;
  13103. + else
  13104. + size_central_dir = uL;
  13105. +
  13106. + /* offset of start of central directory with respect to the starting disk number */
  13107. + offset_central_dir = 0;
  13108. + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
  13109. + err=ZIP_ERRNO;
  13110. + else
  13111. + offset_central_dir = uL;
  13112. +
  13113. +
  13114. + /* zipfile global comment length */
  13115. + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment)!=ZIP_OK)
  13116. + err=ZIP_ERRNO;
  13117. + }
  13118. +
  13119. + if ((central_pos<offset_central_dir+size_central_dir) &&
  13120. + (err==ZIP_OK))
  13121. + err=ZIP_BADZIPFILE;
  13122. +
  13123. + if (err!=ZIP_OK)
  13124. + {
  13125. + ZCLOSE64(pziinit->z_filefunc, pziinit->filestream);
  13126. + return ZIP_ERRNO;
  13127. + }
  13128. +
  13129. + if (size_comment>0)
  13130. + {
  13131. + pziinit->globalcomment = (char*)ALLOC(size_comment+1);
  13132. + if (pziinit->globalcomment)
  13133. + {
  13134. + size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment,size_comment);
  13135. + pziinit->globalcomment[size_comment]=0;
  13136. + }
  13137. + }
  13138. +
  13139. + byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir);
  13140. + pziinit->add_position_when_writting_offset = byte_before_the_zipfile;
  13141. +
  13142. + {
  13143. + ZPOS64_T size_central_dir_to_read = size_central_dir;
  13144. + size_t buf_size = SIZEDATA_INDATABLOCK;
  13145. + void* buf_read = (void*)ALLOC(buf_size);
  13146. + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0)
  13147. + err=ZIP_ERRNO;
  13148. +
  13149. + while ((size_central_dir_to_read>0) && (err==ZIP_OK))
  13150. + {
  13151. + ZPOS64_T read_this = SIZEDATA_INDATABLOCK;
  13152. + if (read_this > size_central_dir_to_read)
  13153. + read_this = size_central_dir_to_read;
  13154. +
  13155. + if (ZREAD64(pziinit->z_filefunc, pziinit->filestream,buf_read,(uLong)read_this) != read_this)
  13156. + err=ZIP_ERRNO;
  13157. +
  13158. + if (err==ZIP_OK)
  13159. + err = add_data_in_datablock(&pziinit->central_dir,buf_read, (uLong)read_this);
  13160. +
  13161. + size_central_dir_to_read-=read_this;
  13162. + }
  13163. + TRYFREE(buf_read);
  13164. + }
  13165. + pziinit->begin_pos = byte_before_the_zipfile;
  13166. + pziinit->number_entry = number_entry_CD;
  13167. +
  13168. + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0)
  13169. + err=ZIP_ERRNO;
  13170. +
  13171. + return err;
  13172. +}
  13173. +
  13174. +
  13175. +#endif /* !NO_ADDFILEINEXISTINGZIP*/
  13176. +
  13177. +
  13178. +/************************************************************/
  13179. +extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def)
  13180. +{
  13181. + zip64_internal ziinit;
  13182. + zip64_internal* zi;
  13183. + int err=ZIP_OK;
  13184. +
  13185. + ziinit.z_filefunc.zseek32_file = NULL;
  13186. + ziinit.z_filefunc.ztell32_file = NULL;
  13187. + if (pzlib_filefunc64_32_def==NULL)
  13188. + fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64);
  13189. + else
  13190. + ziinit.z_filefunc = *pzlib_filefunc64_32_def;
  13191. +
  13192. + ziinit.filestream = ZOPEN64(ziinit.z_filefunc,
  13193. + pathname,
  13194. + (append == APPEND_STATUS_CREATE) ?
  13195. + (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :
  13196. + (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));
  13197. +
  13198. + if (ziinit.filestream == NULL)
  13199. + return NULL;
  13200. +
  13201. + if (append == APPEND_STATUS_CREATEAFTER)
  13202. + ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END);
  13203. +
  13204. + ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream);
  13205. + ziinit.in_opened_file_inzip = 0;
  13206. + ziinit.ci.stream_initialised = 0;
  13207. + ziinit.number_entry = 0;
  13208. + ziinit.add_position_when_writting_offset = 0;
  13209. + init_linkedlist(&(ziinit.central_dir));
  13210. +
  13211. +
  13212. +
  13213. + zi = (zip64_internal*)ALLOC(sizeof(zip64_internal));
  13214. + if (zi==NULL)
  13215. + {
  13216. + ZCLOSE64(ziinit.z_filefunc,ziinit.filestream);
  13217. + return NULL;
  13218. + }
  13219. +
  13220. + /* now we add file in a zipfile */
  13221. +# ifndef NO_ADDFILEINEXISTINGZIP
  13222. + ziinit.globalcomment = NULL;
  13223. + if (append == APPEND_STATUS_ADDINZIP)
  13224. + {
  13225. + // Read and Cache Central Directory Records
  13226. + err = LoadCentralDirectoryRecord(&ziinit);
  13227. + }
  13228. +
  13229. + if (globalcomment)
  13230. + {
  13231. + *globalcomment = ziinit.globalcomment;
  13232. + }
  13233. +# endif /* !NO_ADDFILEINEXISTINGZIP*/
  13234. +
  13235. + if (err != ZIP_OK)
  13236. + {
  13237. +# ifndef NO_ADDFILEINEXISTINGZIP
  13238. + TRYFREE(ziinit.globalcomment);
  13239. +# endif /* !NO_ADDFILEINEXISTINGZIP*/
  13240. + TRYFREE(zi);
  13241. + return NULL;
  13242. + }
  13243. + else
  13244. + {
  13245. + *zi = ziinit;
  13246. + return (zipFile)zi;
  13247. + }
  13248. +}
  13249. +
  13250. +extern zipFile ZEXPORT zipOpen2 (const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def)
  13251. +{
  13252. + if (pzlib_filefunc32_def != NULL)
  13253. + {
  13254. + zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
  13255. + fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
  13256. + return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill);
  13257. + }
  13258. + else
  13259. + return zipOpen3(pathname, append, globalcomment, NULL);
  13260. +}
  13261. +
  13262. +extern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def)
  13263. +{
  13264. + if (pzlib_filefunc_def != NULL)
  13265. + {
  13266. + zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
  13267. + zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
  13268. + zlib_filefunc64_32_def_fill.ztell32_file = NULL;
  13269. + zlib_filefunc64_32_def_fill.zseek32_file = NULL;
  13270. + return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill);
  13271. + }
  13272. + else
  13273. + return zipOpen3(pathname, append, globalcomment, NULL);
  13274. +}
  13275. +
  13276. +
  13277. +
  13278. +extern zipFile ZEXPORT zipOpen (const char* pathname, int append)
  13279. +{
  13280. + return zipOpen3((const void*)pathname,append,NULL,NULL);
  13281. +}
  13282. +
  13283. +extern zipFile ZEXPORT zipOpen64 (const void* pathname, int append)
  13284. +{
  13285. + return zipOpen3(pathname,append,NULL,NULL);
  13286. +}
  13287. +
  13288. +int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local)
  13289. +{
  13290. + /* write the local header */
  13291. + int err;
  13292. + uInt size_filename = (uInt)strlen(filename);
  13293. + uInt size_extrafield = size_extrafield_local;
  13294. +
  13295. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4);
  13296. +
  13297. + if (err==ZIP_OK)
  13298. + {
  13299. + if(zi->ci.zip64)
  13300. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);/* version needed to extract */
  13301. + else
  13302. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */
  13303. + }
  13304. +
  13305. + if (err==ZIP_OK)
  13306. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);
  13307. +
  13308. + if (err==ZIP_OK)
  13309. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);
  13310. +
  13311. + if (err==ZIP_OK)
  13312. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);
  13313. +
  13314. + // CRC / Compressed size / Uncompressed size will be filled in later and rewritten later
  13315. + if (err==ZIP_OK)
  13316. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */
  13317. + if (err==ZIP_OK)
  13318. + {
  13319. + if(zi->ci.zip64)
  13320. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* compressed size, unknown */
  13321. + else
  13322. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */
  13323. + }
  13324. + if (err==ZIP_OK)
  13325. + {
  13326. + if(zi->ci.zip64)
  13327. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* uncompressed size, unknown */
  13328. + else
  13329. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */
  13330. + }
  13331. +
  13332. + if (err==ZIP_OK)
  13333. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);
  13334. +
  13335. + if(zi->ci.zip64)
  13336. + {
  13337. + size_extrafield += 20;
  13338. + }
  13339. +
  13340. + if (err==ZIP_OK)
  13341. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield,2);
  13342. +
  13343. + if ((err==ZIP_OK) && (size_filename > 0))
  13344. + {
  13345. + if (ZWRITE64(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)
  13346. + err = ZIP_ERRNO;
  13347. + }
  13348. +
  13349. + if ((err==ZIP_OK) && (size_extrafield_local > 0))
  13350. + {
  13351. + if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local)
  13352. + err = ZIP_ERRNO;
  13353. + }
  13354. +
  13355. +
  13356. + if ((err==ZIP_OK) && (zi->ci.zip64))
  13357. + {
  13358. + // write the Zip64 extended info
  13359. + short HeaderID = 1;
  13360. + short DataSize = 16;
  13361. + ZPOS64_T CompressedSize = 0;
  13362. + ZPOS64_T UncompressedSize = 0;
  13363. +
  13364. + // Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file)
  13365. + zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream);
  13366. +
  13367. + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)HeaderID,2);
  13368. + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)DataSize,2);
  13369. +
  13370. + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8);
  13371. + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8);
  13372. + }
  13373. +
  13374. + return err;
  13375. +}
  13376. +
  13377. +/*
  13378. + NOTE.
  13379. + When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped
  13380. + before calling this function it can be done with zipRemoveExtraInfoBlock
  13381. +
  13382. + It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize
  13383. + unnecessary allocations.
  13384. + */
  13385. +extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
  13386. + const void* extrafield_local, uInt size_extrafield_local,
  13387. + const void* extrafield_global, uInt size_extrafield_global,
  13388. + const char* comment, int method, int level, int raw,
  13389. + int windowBits,int memLevel, int strategy,
  13390. + const char* password, uLong crcForCrypting,
  13391. + uLong versionMadeBy, uLong flagBase, int zip64)
  13392. +{
  13393. + zip64_internal* zi;
  13394. + uInt size_filename;
  13395. + uInt size_comment;
  13396. + uInt i;
  13397. + int err = ZIP_OK;
  13398. +
  13399. +# ifdef NOCRYPT
  13400. + if (password != NULL)
  13401. + return ZIP_PARAMERROR;
  13402. +# endif
  13403. +
  13404. + if (file == NULL)
  13405. + return ZIP_PARAMERROR;
  13406. +
  13407. +#ifdef HAVE_BZIP2
  13408. + if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED))
  13409. + return ZIP_PARAMERROR;
  13410. +#else
  13411. + if ((method!=0) && (method!=Z_DEFLATED))
  13412. + return ZIP_PARAMERROR;
  13413. +#endif
  13414. +
  13415. + zi = (zip64_internal*)file;
  13416. +
  13417. + if (zi->in_opened_file_inzip == 1)
  13418. + {
  13419. + err = zipCloseFileInZip (file);
  13420. + if (err != ZIP_OK)
  13421. + return err;
  13422. + }
  13423. +
  13424. + if (filename==NULL)
  13425. + filename="-";
  13426. +
  13427. + if (comment==NULL)
  13428. + size_comment = 0;
  13429. + else
  13430. + size_comment = (uInt)strlen(comment);
  13431. +
  13432. + size_filename = (uInt)strlen(filename);
  13433. +
  13434. + if (zipfi == NULL)
  13435. + zi->ci.dosDate = 0;
  13436. + else
  13437. + {
  13438. + if (zipfi->dosDate != 0)
  13439. + zi->ci.dosDate = zipfi->dosDate;
  13440. + else
  13441. + zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date);
  13442. + }
  13443. +
  13444. + zi->ci.flag = flagBase;
  13445. + if ((level==8) || (level==9))
  13446. + zi->ci.flag |= 2;
  13447. + if ((level==2))
  13448. + zi->ci.flag |= 4;
  13449. + if ((level==1))
  13450. + zi->ci.flag |= 6;
  13451. + if (password != NULL)
  13452. + zi->ci.flag |= 1;
  13453. +
  13454. + zi->ci.crc32 = 0;
  13455. + zi->ci.method = method;
  13456. + zi->ci.encrypt = 0;
  13457. + zi->ci.stream_initialised = 0;
  13458. + zi->ci.pos_in_buffered_data = 0;
  13459. + zi->ci.raw = raw;
  13460. + zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream);
  13461. +
  13462. + zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment;
  13463. + zi->ci.size_centralExtraFree = 32; // Extra space we have reserved in case we need to add ZIP64 extra info data
  13464. +
  13465. + zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree);
  13466. +
  13467. + zi->ci.size_centralExtra = size_extrafield_global;
  13468. + zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
  13469. + /* version info */
  13470. + zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2);
  13471. + zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);
  13472. + zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
  13473. + zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
  13474. + zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
  13475. + zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
  13476. + zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
  13477. + zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
  13478. + zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
  13479. + zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
  13480. + zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
  13481. + zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
  13482. +
  13483. + if (zipfi==NULL)
  13484. + zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
  13485. + else
  13486. + zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
  13487. +
  13488. + if (zipfi==NULL)
  13489. + zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
  13490. + else
  13491. + zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
  13492. +
  13493. + if(zi->ci.pos_local_header >= 0xffffffff)
  13494. + zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4);
  13495. + else
  13496. + zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writting_offset,4);
  13497. +
  13498. + for (i=0;i<size_filename;i++)
  13499. + *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
  13500. +
  13501. + for (i=0;i<size_extrafield_global;i++)
  13502. + *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
  13503. + *(((const char*)extrafield_global)+i);
  13504. +
  13505. + for (i=0;i<size_comment;i++)
  13506. + *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
  13507. + size_extrafield_global+i) = *(comment+i);
  13508. + if (zi->ci.central_header == NULL)
  13509. + return ZIP_INTERNALERROR;
  13510. +
  13511. + zi->ci.zip64 = zip64;
  13512. + zi->ci.totalCompressedData = 0;
  13513. + zi->ci.totalUncompressedData = 0;
  13514. + zi->ci.pos_zip64extrainfo = 0;
  13515. +
  13516. + err = Write_LocalFileHeader(zi, filename, size_extrafield_local, extrafield_local);
  13517. +
  13518. +#ifdef HAVE_BZIP2
  13519. + zi->ci.bstream.avail_in = (uInt)0;
  13520. + zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
  13521. + zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
  13522. + zi->ci.bstream.total_in_hi32 = 0;
  13523. + zi->ci.bstream.total_in_lo32 = 0;
  13524. + zi->ci.bstream.total_out_hi32 = 0;
  13525. + zi->ci.bstream.total_out_lo32 = 0;
  13526. +#endif
  13527. +
  13528. + zi->ci.stream.avail_in = (uInt)0;
  13529. + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
  13530. + zi->ci.stream.next_out = zi->ci.buffered_data;
  13531. + zi->ci.stream.total_in = 0;
  13532. + zi->ci.stream.total_out = 0;
  13533. + zi->ci.stream.data_type = Z_BINARY;
  13534. +
  13535. +#ifdef HAVE_BZIP2
  13536. + if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
  13537. +#else
  13538. + if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
  13539. +#endif
  13540. + {
  13541. + if(zi->ci.method == Z_DEFLATED)
  13542. + {
  13543. + zi->ci.stream.zalloc = (alloc_func)0;
  13544. + zi->ci.stream.zfree = (free_func)0;
  13545. + zi->ci.stream.opaque = (voidpf)0;
  13546. +
  13547. + if (windowBits>0)
  13548. + windowBits = -windowBits;
  13549. +
  13550. + err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy);
  13551. +
  13552. + if (err==Z_OK)
  13553. + zi->ci.stream_initialised = Z_DEFLATED;
  13554. + }
  13555. + else if(zi->ci.method == Z_BZIP2ED)
  13556. + {
  13557. +#ifdef HAVE_BZIP2
  13558. + // Init BZip stuff here
  13559. + zi->ci.bstream.bzalloc = 0;
  13560. + zi->ci.bstream.bzfree = 0;
  13561. + zi->ci.bstream.opaque = (voidpf)0;
  13562. +
  13563. + err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35);
  13564. + if(err == BZ_OK)
  13565. + zi->ci.stream_initialised = Z_BZIP2ED;
  13566. +#endif
  13567. + }
  13568. +
  13569. + }
  13570. +
  13571. +# ifndef NOCRYPT
  13572. + zi->ci.crypt_header_size = 0;
  13573. + if ((err==Z_OK) && (password != NULL))
  13574. + {
  13575. + unsigned char bufHead[RAND_HEAD_LEN];
  13576. + unsigned int sizeHead;
  13577. + zi->ci.encrypt = 1;
  13578. + zi->ci.pcrc_32_tab = get_crc_table();
  13579. + /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
  13580. +
  13581. + sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);
  13582. + zi->ci.crypt_header_size = sizeHead;
  13583. +
  13584. + if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
  13585. + err = ZIP_ERRNO;
  13586. + }
  13587. +# endif
  13588. +
  13589. + if (err==Z_OK)
  13590. + zi->in_opened_file_inzip = 1;
  13591. + return err;
  13592. +}
  13593. +
  13594. +extern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
  13595. + const void* extrafield_local, uInt size_extrafield_local,
  13596. + const void* extrafield_global, uInt size_extrafield_global,
  13597. + const char* comment, int method, int level, int raw,
  13598. + int windowBits,int memLevel, int strategy,
  13599. + const char* password, uLong crcForCrypting,
  13600. + uLong versionMadeBy, uLong flagBase)
  13601. +{
  13602. + return zipOpenNewFileInZip4_64 (file, filename, zipfi,
  13603. + extrafield_local, size_extrafield_local,
  13604. + extrafield_global, size_extrafield_global,
  13605. + comment, method, level, raw,
  13606. + windowBits, memLevel, strategy,
  13607. + password, crcForCrypting, versionMadeBy, flagBase, 0);
  13608. +}
  13609. +
  13610. +extern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
  13611. + const void* extrafield_local, uInt size_extrafield_local,
  13612. + const void* extrafield_global, uInt size_extrafield_global,
  13613. + const char* comment, int method, int level, int raw,
  13614. + int windowBits,int memLevel, int strategy,
  13615. + const char* password, uLong crcForCrypting)
  13616. +{
  13617. + return zipOpenNewFileInZip4_64 (file, filename, zipfi,
  13618. + extrafield_local, size_extrafield_local,
  13619. + extrafield_global, size_extrafield_global,
  13620. + comment, method, level, raw,
  13621. + windowBits, memLevel, strategy,
  13622. + password, crcForCrypting, VERSIONMADEBY, 0, 0);
  13623. +}
  13624. +
  13625. +extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
  13626. + const void* extrafield_local, uInt size_extrafield_local,
  13627. + const void* extrafield_global, uInt size_extrafield_global,
  13628. + const char* comment, int method, int level, int raw,
  13629. + int windowBits,int memLevel, int strategy,
  13630. + const char* password, uLong crcForCrypting, int zip64)
  13631. +{
  13632. + return zipOpenNewFileInZip4_64 (file, filename, zipfi,
  13633. + extrafield_local, size_extrafield_local,
  13634. + extrafield_global, size_extrafield_global,
  13635. + comment, method, level, raw,
  13636. + windowBits, memLevel, strategy,
  13637. + password, crcForCrypting, VERSIONMADEBY, 0, zip64);
  13638. +}
  13639. +
  13640. +extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi,
  13641. + const void* extrafield_local, uInt size_extrafield_local,
  13642. + const void* extrafield_global, uInt size_extrafield_global,
  13643. + const char* comment, int method, int level, int raw)
  13644. +{
  13645. + return zipOpenNewFileInZip4_64 (file, filename, zipfi,
  13646. + extrafield_local, size_extrafield_local,
  13647. + extrafield_global, size_extrafield_global,
  13648. + comment, method, level, raw,
  13649. + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
  13650. + NULL, 0, VERSIONMADEBY, 0, 0);
  13651. +}
  13652. +
  13653. +extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
  13654. + const void* extrafield_local, uInt size_extrafield_local,
  13655. + const void* extrafield_global, uInt size_extrafield_global,
  13656. + const char* comment, int method, int level, int raw, int zip64)
  13657. +{
  13658. + return zipOpenNewFileInZip4_64 (file, filename, zipfi,
  13659. + extrafield_local, size_extrafield_local,
  13660. + extrafield_global, size_extrafield_global,
  13661. + comment, method, level, raw,
  13662. + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
  13663. + NULL, 0, VERSIONMADEBY, 0, zip64);
  13664. +}
  13665. +
  13666. +extern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
  13667. + const void* extrafield_local, uInt size_extrafield_local,
  13668. + const void*extrafield_global, uInt size_extrafield_global,
  13669. + const char* comment, int method, int level, int zip64)
  13670. +{
  13671. + return zipOpenNewFileInZip4_64 (file, filename, zipfi,
  13672. + extrafield_local, size_extrafield_local,
  13673. + extrafield_global, size_extrafield_global,
  13674. + comment, method, level, 0,
  13675. + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
  13676. + NULL, 0, VERSIONMADEBY, 0, zip64);
  13677. +}
  13678. +
  13679. +extern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi,
  13680. + const void* extrafield_local, uInt size_extrafield_local,
  13681. + const void*extrafield_global, uInt size_extrafield_global,
  13682. + const char* comment, int method, int level)
  13683. +{
  13684. + return zipOpenNewFileInZip4_64 (file, filename, zipfi,
  13685. + extrafield_local, size_extrafield_local,
  13686. + extrafield_global, size_extrafield_global,
  13687. + comment, method, level, 0,
  13688. + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
  13689. + NULL, 0, VERSIONMADEBY, 0, 0);
  13690. +}
  13691. +
  13692. +local int zip64FlushWriteBuffer(zip64_internal* zi)
  13693. +{
  13694. + int err=ZIP_OK;
  13695. +
  13696. + if (zi->ci.encrypt != 0)
  13697. + {
  13698. +#ifndef NOCRYPT
  13699. + uInt i;
  13700. + int t;
  13701. + for (i=0;i<zi->ci.pos_in_buffered_data;i++)
  13702. + zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t);
  13703. +#endif
  13704. + }
  13705. +
  13706. + if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data)
  13707. + err = ZIP_ERRNO;
  13708. +
  13709. + zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data;
  13710. +
  13711. +#ifdef HAVE_BZIP2
  13712. + if(zi->ci.method == Z_BZIP2ED)
  13713. + {
  13714. + zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32;
  13715. + zi->ci.bstream.total_in_lo32 = 0;
  13716. + zi->ci.bstream.total_in_hi32 = 0;
  13717. + }
  13718. + else
  13719. +#endif
  13720. + {
  13721. + zi->ci.totalUncompressedData += zi->ci.stream.total_in;
  13722. + zi->ci.stream.total_in = 0;
  13723. + }
  13724. +
  13725. +
  13726. + zi->ci.pos_in_buffered_data = 0;
  13727. +
  13728. + return err;
  13729. +}
  13730. +
  13731. +extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len)
  13732. +{
  13733. + zip64_internal* zi;
  13734. + int err=ZIP_OK;
  13735. +
  13736. + if (file == NULL)
  13737. + return ZIP_PARAMERROR;
  13738. + zi = (zip64_internal*)file;
  13739. +
  13740. + if (zi->in_opened_file_inzip == 0)
  13741. + return ZIP_PARAMERROR;
  13742. +
  13743. + zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len);
  13744. +
  13745. +#ifdef HAVE_BZIP2
  13746. + if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw))
  13747. + {
  13748. + zi->ci.bstream.next_in = (void*)buf;
  13749. + zi->ci.bstream.avail_in = len;
  13750. + err = BZ_RUN_OK;
  13751. +
  13752. + while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0))
  13753. + {
  13754. + if (zi->ci.bstream.avail_out == 0)
  13755. + {
  13756. + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
  13757. + err = ZIP_ERRNO;
  13758. + zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
  13759. + zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
  13760. + }
  13761. +
  13762. +
  13763. + if(err != BZ_RUN_OK)
  13764. + break;
  13765. +
  13766. + if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
  13767. + {
  13768. + uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32;
  13769. +// uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32;
  13770. + err=BZ2_bzCompress(&zi->ci.bstream, BZ_RUN);
  13771. +
  13772. + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ;
  13773. + }
  13774. + }
  13775. +
  13776. + if(err == BZ_RUN_OK)
  13777. + err = ZIP_OK;
  13778. + }
  13779. + else
  13780. +#endif
  13781. + {
  13782. + zi->ci.stream.next_in = (Bytef*)buf;
  13783. + zi->ci.stream.avail_in = len;
  13784. +
  13785. + while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
  13786. + {
  13787. + if (zi->ci.stream.avail_out == 0)
  13788. + {
  13789. + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
  13790. + err = ZIP_ERRNO;
  13791. + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
  13792. + zi->ci.stream.next_out = zi->ci.buffered_data;
  13793. + }
  13794. +
  13795. +
  13796. + if(err != ZIP_OK)
  13797. + break;
  13798. +
  13799. + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
  13800. + {
  13801. + uLong uTotalOutBefore = zi->ci.stream.total_out;
  13802. + err=deflate(&zi->ci.stream, Z_NO_FLUSH);
  13803. + if(uTotalOutBefore > zi->ci.stream.total_out)
  13804. + {
  13805. + int bBreak = 0;
  13806. + bBreak++;
  13807. + }
  13808. +
  13809. + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
  13810. + }
  13811. + else
  13812. + {
  13813. + uInt copy_this,i;
  13814. + if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
  13815. + copy_this = zi->ci.stream.avail_in;
  13816. + else
  13817. + copy_this = zi->ci.stream.avail_out;
  13818. +
  13819. + for (i = 0; i < copy_this; i++)
  13820. + *(((char*)zi->ci.stream.next_out)+i) =
  13821. + *(((const char*)zi->ci.stream.next_in)+i);
  13822. + {
  13823. + zi->ci.stream.avail_in -= copy_this;
  13824. + zi->ci.stream.avail_out-= copy_this;
  13825. + zi->ci.stream.next_in+= copy_this;
  13826. + zi->ci.stream.next_out+= copy_this;
  13827. + zi->ci.stream.total_in+= copy_this;
  13828. + zi->ci.stream.total_out+= copy_this;
  13829. + zi->ci.pos_in_buffered_data += copy_this;
  13830. + }
  13831. + }
  13832. + }// while(...)
  13833. + }
  13834. +
  13835. + return err;
  13836. +}
  13837. +
  13838. +extern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32)
  13839. +{
  13840. + return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32);
  13841. +}
  13842. +
  13843. +extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32)
  13844. +{
  13845. + zip64_internal* zi;
  13846. + ZPOS64_T compressed_size;
  13847. + uLong invalidValue = 0xffffffff;
  13848. + short datasize = 0;
  13849. + int err=ZIP_OK;
  13850. +
  13851. + if (file == NULL)
  13852. + return ZIP_PARAMERROR;
  13853. + zi = (zip64_internal*)file;
  13854. +
  13855. + if (zi->in_opened_file_inzip == 0)
  13856. + return ZIP_PARAMERROR;
  13857. + zi->ci.stream.avail_in = 0;
  13858. +
  13859. + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
  13860. + {
  13861. + while (err==ZIP_OK)
  13862. + {
  13863. + uLong uTotalOutBefore;
  13864. + if (zi->ci.stream.avail_out == 0)
  13865. + {
  13866. + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
  13867. + err = ZIP_ERRNO;
  13868. + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
  13869. + zi->ci.stream.next_out = zi->ci.buffered_data;
  13870. + }
  13871. + uTotalOutBefore = zi->ci.stream.total_out;
  13872. + err=deflate(&zi->ci.stream, Z_FINISH);
  13873. + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
  13874. + }
  13875. + }
  13876. + else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
  13877. + {
  13878. +#ifdef HAVE_BZIP2
  13879. + err = BZ_FINISH_OK;
  13880. + while (err==BZ_FINISH_OK)
  13881. + {
  13882. + uLong uTotalOutBefore;
  13883. + if (zi->ci.bstream.avail_out == 0)
  13884. + {
  13885. + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
  13886. + err = ZIP_ERRNO;
  13887. + zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
  13888. + zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
  13889. + }
  13890. + uTotalOutBefore = zi->ci.bstream.total_out_lo32;
  13891. + err=BZ2_bzCompress(&zi->ci.bstream, BZ_FINISH);
  13892. + if(err == BZ_STREAM_END)
  13893. + err = Z_STREAM_END;
  13894. +
  13895. + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore);
  13896. + }
  13897. +
  13898. + if(err == BZ_FINISH_OK)
  13899. + err = ZIP_OK;
  13900. +#endif
  13901. + }
  13902. +
  13903. + if (err==Z_STREAM_END)
  13904. + err=ZIP_OK; /* this is normal */
  13905. +
  13906. + if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
  13907. + {
  13908. + if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO)
  13909. + err = ZIP_ERRNO;
  13910. + }
  13911. +
  13912. + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
  13913. + {
  13914. + int tmp_err = deflateEnd(&zi->ci.stream);
  13915. + if (err == ZIP_OK)
  13916. + err = tmp_err;
  13917. + zi->ci.stream_initialised = 0;
  13918. + }
  13919. +#ifdef HAVE_BZIP2
  13920. + else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
  13921. + {
  13922. + int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream);
  13923. + if (err==ZIP_OK)
  13924. + err = tmperr;
  13925. + zi->ci.stream_initialised = 0;
  13926. + }
  13927. +#endif
  13928. +
  13929. + if (!zi->ci.raw)
  13930. + {
  13931. + crc32 = (uLong)zi->ci.crc32;
  13932. + uncompressed_size = zi->ci.totalUncompressedData;
  13933. + }
  13934. + compressed_size = zi->ci.totalCompressedData;
  13935. +
  13936. +# ifndef NOCRYPT
  13937. + compressed_size += zi->ci.crypt_header_size;
  13938. +# endif
  13939. +
  13940. + // update Current Item crc and sizes,
  13941. + if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff)
  13942. + {
  13943. + /*version Made by*/
  13944. + zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2);
  13945. + /*version needed*/
  13946. + zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)45,2);
  13947. +
  13948. + }
  13949. +
  13950. + zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/
  13951. +
  13952. +
  13953. + if(compressed_size >= 0xffffffff)
  13954. + zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/
  13955. + else
  13956. + zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/
  13957. +
  13958. + /// set internal file attributes field
  13959. + if (zi->ci.stream.data_type == Z_ASCII)
  13960. + zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
  13961. +
  13962. + if(uncompressed_size >= 0xffffffff)
  13963. + zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/
  13964. + else
  13965. + zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/
  13966. +
  13967. + // Add ZIP64 extra info field for uncompressed size
  13968. + if(uncompressed_size >= 0xffffffff)
  13969. + datasize += 8;
  13970. +
  13971. + // Add ZIP64 extra info field for compressed size
  13972. + if(compressed_size >= 0xffffffff)
  13973. + datasize += 8;
  13974. +
  13975. + // Add ZIP64 extra info field for relative offset to local file header of current file
  13976. + if(zi->ci.pos_local_header >= 0xffffffff)
  13977. + datasize += 8;
  13978. +
  13979. + if(datasize > 0)
  13980. + {
  13981. + char* p = NULL;
  13982. +
  13983. + if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree)
  13984. + {
  13985. + // we can not write more data to the buffer that we have room for.
  13986. + return ZIP_BADZIPFILE;
  13987. + }
  13988. +
  13989. + p = zi->ci.central_header + zi->ci.size_centralheader;
  13990. +
  13991. + // Add Extra Information Header for 'ZIP64 information'
  13992. + zip64local_putValue_inmemory(p, 0x0001, 2); // HeaderID
  13993. + p += 2;
  13994. + zip64local_putValue_inmemory(p, datasize, 2); // DataSize
  13995. + p += 2;
  13996. +
  13997. + if(uncompressed_size >= 0xffffffff)
  13998. + {
  13999. + zip64local_putValue_inmemory(p, uncompressed_size, 8);
  14000. + p += 8;
  14001. + }
  14002. +
  14003. + if(compressed_size >= 0xffffffff)
  14004. + {
  14005. + zip64local_putValue_inmemory(p, compressed_size, 8);
  14006. + p += 8;
  14007. + }
  14008. +
  14009. + if(zi->ci.pos_local_header >= 0xffffffff)
  14010. + {
  14011. + zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8);
  14012. + p += 8;
  14013. + }
  14014. +
  14015. + // Update how much extra free space we got in the memory buffer
  14016. + // and increase the centralheader size so the new ZIP64 fields are included
  14017. + // ( 4 below is the size of HeaderID and DataSize field )
  14018. + zi->ci.size_centralExtraFree -= datasize + 4;
  14019. + zi->ci.size_centralheader += datasize + 4;
  14020. +
  14021. + // Update the extra info size field
  14022. + zi->ci.size_centralExtra += datasize + 4;
  14023. + zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2);
  14024. + }
  14025. +
  14026. + if (err==ZIP_OK)
  14027. + err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader);
  14028. +
  14029. + free(zi->ci.central_header);
  14030. +
  14031. + if (err==ZIP_OK)
  14032. + {
  14033. + // Update the LocalFileHeader with the new values.
  14034. +
  14035. + ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
  14036. +
  14037. + if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
  14038. + err = ZIP_ERRNO;
  14039. +
  14040. + if (err==ZIP_OK)
  14041. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
  14042. +
  14043. + if(uncompressed_size >= 0xffffffff)
  14044. + {
  14045. + if(zi->ci.pos_zip64extrainfo > 0)
  14046. + {
  14047. + // Update the size in the ZIP64 extended field.
  14048. + if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0)
  14049. + err = ZIP_ERRNO;
  14050. +
  14051. + if (err==ZIP_OK) /* compressed size, unknown */
  14052. + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8);
  14053. +
  14054. + if (err==ZIP_OK) /* uncompressed size, unknown */
  14055. + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8);
  14056. + }
  14057. + }
  14058. + else
  14059. + {
  14060. + if (err==ZIP_OK) /* compressed size, unknown */
  14061. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
  14062. +
  14063. + if (err==ZIP_OK) /* uncompressed size, unknown */
  14064. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
  14065. + }
  14066. +
  14067. + if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
  14068. + err = ZIP_ERRNO;
  14069. + }
  14070. +
  14071. + zi->number_entry ++;
  14072. + zi->in_opened_file_inzip = 0;
  14073. +
  14074. + return err;
  14075. +}
  14076. +
  14077. +extern int ZEXPORT zipCloseFileInZip (zipFile file)
  14078. +{
  14079. + return zipCloseFileInZipRaw (file,0,0);
  14080. +}
  14081. +
  14082. +int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip)
  14083. +{
  14084. + int err = ZIP_OK;
  14085. + ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset;
  14086. +
  14087. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4);
  14088. +
  14089. + /*num disks*/
  14090. + if (err==ZIP_OK) /* number of the disk with the start of the central directory */
  14091. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
  14092. +
  14093. + /*relative offset*/
  14094. + if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */
  14095. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8);
  14096. +
  14097. + /*total disks*/ /* Do not support spawning of disk so always say 1 here*/
  14098. + if (err==ZIP_OK) /* number of the disk with the start of the central directory */
  14099. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4);
  14100. +
  14101. + return err;
  14102. +}
  14103. +
  14104. +int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
  14105. +{
  14106. + int err = ZIP_OK;
  14107. +
  14108. + uLong Zip64DataSize = 44;
  14109. +
  14110. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4);
  14111. +
  14112. + if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */
  14113. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); // why ZPOS64_T of this ?
  14114. +
  14115. + if (err==ZIP_OK) /* version made by */
  14116. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
  14117. +
  14118. + if (err==ZIP_OK) /* version needed */
  14119. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
  14120. +
  14121. + if (err==ZIP_OK) /* number of this disk */
  14122. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
  14123. +
  14124. + if (err==ZIP_OK) /* number of the disk with the start of the central directory */
  14125. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
  14126. +
  14127. + if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
  14128. + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
  14129. +
  14130. + if (err==ZIP_OK) /* total number of entries in the central dir */
  14131. + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
  14132. +
  14133. + if (err==ZIP_OK) /* size of the central directory */
  14134. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8);
  14135. +
  14136. + if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
  14137. + {
  14138. + ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
  14139. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8);
  14140. + }
  14141. + return err;
  14142. +}
  14143. +int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
  14144. +{
  14145. + int err = ZIP_OK;
  14146. +
  14147. + /*signature*/
  14148. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);
  14149. +
  14150. + if (err==ZIP_OK) /* number of this disk */
  14151. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
  14152. +
  14153. + if (err==ZIP_OK) /* number of the disk with the start of the central directory */
  14154. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
  14155. +
  14156. + if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
  14157. + {
  14158. + {
  14159. + if(zi->number_entry >= 0xFFFF)
  14160. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record
  14161. + else
  14162. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
  14163. + }
  14164. + }
  14165. +
  14166. + if (err==ZIP_OK) /* total number of entries in the central dir */
  14167. + {
  14168. + if(zi->number_entry >= 0xFFFF)
  14169. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record
  14170. + else
  14171. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
  14172. + }
  14173. +
  14174. + if (err==ZIP_OK) /* size of the central directory */
  14175. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);
  14176. +
  14177. + if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
  14178. + {
  14179. + ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
  14180. + if(pos >= 0xffffffff)
  14181. + {
  14182. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4);
  14183. + }
  14184. + else
  14185. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);
  14186. + }
  14187. +
  14188. + return err;
  14189. +}
  14190. +
  14191. +int Write_GlobalComment(zip64_internal* zi, const char* global_comment)
  14192. +{
  14193. + int err = ZIP_OK;
  14194. + uInt size_global_comment = 0;
  14195. +
  14196. + if(global_comment != NULL)
  14197. + size_global_comment = (uInt)strlen(global_comment);
  14198. +
  14199. + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);
  14200. +
  14201. + if (err == ZIP_OK && size_global_comment > 0)
  14202. + {
  14203. + if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment)
  14204. + err = ZIP_ERRNO;
  14205. + }
  14206. + return err;
  14207. +}
  14208. +
  14209. +extern int ZEXPORT zipClose (zipFile file, const char* global_comment)
  14210. +{
  14211. + zip64_internal* zi;
  14212. + int err = 0;
  14213. + uLong size_centraldir = 0;
  14214. + ZPOS64_T centraldir_pos_inzip;
  14215. + ZPOS64_T pos;
  14216. +
  14217. + if (file == NULL)
  14218. + return ZIP_PARAMERROR;
  14219. +
  14220. + zi = (zip64_internal*)file;
  14221. +
  14222. + if (zi->in_opened_file_inzip == 1)
  14223. + {
  14224. + err = zipCloseFileInZip (file);
  14225. + }
  14226. +
  14227. +#ifndef NO_ADDFILEINEXISTINGZIP
  14228. + if (global_comment==NULL)
  14229. + global_comment = zi->globalcomment;
  14230. +#endif
  14231. +
  14232. + centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
  14233. +
  14234. + if (err==ZIP_OK)
  14235. + {
  14236. + linkedlist_datablock_internal* ldi = zi->central_dir.first_block;
  14237. + while (ldi!=NULL)
  14238. + {
  14239. + if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
  14240. + {
  14241. + if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block)
  14242. + err = ZIP_ERRNO;
  14243. + }
  14244. +
  14245. + size_centraldir += ldi->filled_in_this_block;
  14246. + ldi = ldi->next_datablock;
  14247. + }
  14248. + }
  14249. + free_linkedlist(&(zi->central_dir));
  14250. +
  14251. + pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
  14252. + if(pos >= 0xffffffff)
  14253. + {
  14254. + ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream);
  14255. + Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
  14256. +
  14257. + Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos);
  14258. + }
  14259. +
  14260. + if (err==ZIP_OK)
  14261. + err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
  14262. +
  14263. + if(err == ZIP_OK)
  14264. + err = Write_GlobalComment(zi, global_comment);
  14265. +
  14266. + if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0)
  14267. + if (err == ZIP_OK)
  14268. + err = ZIP_ERRNO;
  14269. +
  14270. +#ifndef NO_ADDFILEINEXISTINGZIP
  14271. + TRYFREE(zi->globalcomment);
  14272. +#endif
  14273. + TRYFREE(zi);
  14274. +
  14275. + return err;
  14276. +}
  14277. +
  14278. +extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader)
  14279. +{
  14280. + char* p = pData;
  14281. + int size = 0;
  14282. + char* pNewHeader;
  14283. + char* pTmp;
  14284. + short header;
  14285. + short dataSize;
  14286. +
  14287. + int retVal = ZIP_OK;
  14288. +
  14289. + if(pData == NULL || *dataLen < 4)
  14290. + return ZIP_PARAMERROR;
  14291. +
  14292. + pNewHeader = (char*)ALLOC(*dataLen);
  14293. + pTmp = pNewHeader;
  14294. +
  14295. + while(p < (pData + *dataLen))
  14296. + {
  14297. + header = *(short*)p;
  14298. + dataSize = *(((short*)p)+1);
  14299. +
  14300. + if( header == sHeader ) // Header found.
  14301. + {
  14302. + p += dataSize + 4; // skip it. do not copy to temp buffer
  14303. + }
  14304. + else
  14305. + {
  14306. + // Extra Info block should not be removed, So copy it to the temp buffer.
  14307. + memcpy(pTmp, p, dataSize + 4);
  14308. + p += dataSize + 4;
  14309. + size += dataSize + 4;
  14310. + }
  14311. +
  14312. + }
  14313. +
  14314. + if(size < *dataLen)
  14315. + {
  14316. + // clean old extra info block.
  14317. + memset(pData,0, *dataLen);
  14318. +
  14319. + // copy the new extra info block over the old
  14320. + if(size > 0)
  14321. + memcpy(pData, pNewHeader, size);
  14322. +
  14323. + // set the new extra info size
  14324. + *dataLen = size;
  14325. +
  14326. + retVal = ZIP_OK;
  14327. + }
  14328. + else
  14329. + retVal = ZIP_ERRNO;
  14330. +
  14331. + TRYFREE(pNewHeader);
  14332. +
  14333. + return retVal;
  14334. +}
Add Comment
Please, Sign In to add comment