dreamcast_scramble.cc Source File

Back to the index.

dreamcast_scramble.cc
Go to the documentation of this file.
1 /*
2  * COMMENT: Dreamcast emulation (helper module)
3  *
4  * This is from Marcus Comstedt's Dreamcast development files
5  * (http://mc.pp.se/dc/files/scramble.c). Public Domain, according to
6  * Marcus software page.
7  *
8  * The only modification done to make it fit into the emulator is that
9  * it is executed internally from src/file.c.
10  */
11 
12 /* #define STAND_ALONE */
13 
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 
18 #define MAXCHUNK (2048*1024)
19 
20 static unsigned int seed;
21 
22 void my_srand(unsigned int n)
23 {
24  seed = n & 0xffff;
25 }
26 
27 unsigned int my_rand(void)
28 {
29  seed = (seed * 2109 + 9273) & 0x7fff;
30  return (seed + 0xc000) & 0xffff;
31 }
32 
33 void load(FILE *fh, unsigned char *ptr, unsigned long sz)
34 {
35  if(fread(ptr, 1, sz, fh) != sz)
36  {
37  fprintf(stderr, "Read error!\n");
38  exit(1);
39  }
40 }
41 
42 void load_chunk(FILE *fh, unsigned char *ptr, unsigned long sz)
43 {
44  static int idx[MAXCHUNK/32];
45  int i;
46 
47  /* Convert chunk size to number of slices */
48  sz /= 32;
49 
50  /* Initialize index table with unity,
51  so that each slice gets loaded exactly once */
52  for(i = 0; i < (int)sz; i++)
53  idx[i] = i;
54 
55  for(i = sz-1; i >= 0; --i)
56  {
57  /* Select a replacement index */
58  int x = (my_rand() * i) >> 16;
59 
60  /* Swap */
61  int tmp = idx[i];
62  idx[i] = idx[x];
63  idx[x] = tmp;
64 
65  /* Load resulting slice */
66  load(fh, ptr+32*idx[i], 32);
67  }
68 }
69 
70 void load_file(FILE *fh, unsigned char *ptr, unsigned long filesz)
71 {
72  unsigned long chunksz;
73 
74  my_srand(filesz);
75 
76  /* Descramble 2 meg blocks for as long as possible, then
77  gradually reduce the window down to 32 bytes (1 slice) */
78  for(chunksz = MAXCHUNK; chunksz >= 32; chunksz >>= 1)
79  while(filesz >= chunksz)
80  {
81  load_chunk(fh, ptr, chunksz);
82  filesz -= chunksz;
83  ptr += chunksz;
84  }
85 
86  /* Load final incomplete slice */
87  if(filesz)
88  load(fh, ptr, filesz);
89 }
90 
91 void read_file(char *filename, unsigned char **ptr, unsigned long *sz)
92 {
93  FILE *fh = fopen(filename, "rb");
94  if(fh == NULL)
95  {
96  fprintf(stderr, "Can't open \"%s\".\n", filename);
97  exit(1);
98  }
99  if(fseek(fh, 0, SEEK_END)<0)
100  {
101  fprintf(stderr, "Seek error.\n");
102  exit(1);
103  }
104  *sz = ftell(fh);
105  *ptr = (unsigned char *) malloc(*sz);
106  if( *ptr == NULL )
107  {
108  fprintf(stderr, "Out of memory.\n");
109  exit(1);
110  }
111  if(fseek(fh, 0, SEEK_SET)<0)
112  {
113  fprintf(stderr, "Seek error.\n");
114  exit(1);
115  }
116  load_file(fh, *ptr, *sz);
117  fclose(fh);
118 }
119 
120 void save(FILE *fh, unsigned char *ptr, unsigned long sz)
121 {
122  if(fwrite(ptr, 1, sz, fh) != sz)
123  {
124  fprintf(stderr, "Write error!\n");
125  exit(1);
126  }
127 }
128 
129 void save_chunk(FILE *fh, unsigned char *ptr, unsigned long sz)
130 {
131  static int idx[MAXCHUNK/32];
132  int i;
133 
134  /* Convert chunk size to number of slices */
135  sz /= 32;
136 
137  /* Initialize index table with unity,
138  so that each slice gets saved exactly once */
139  for(i = 0; i < (int)sz; i++)
140  idx[i] = i;
141 
142  for(i = sz-1; i >= 0; --i)
143  {
144  /* Select a replacement index */
145  int x = (my_rand() * i) >> 16;
146 
147  /* Swap */
148  int tmp = idx[i];
149  idx[i] = idx[x];
150  idx[x] = tmp;
151 
152  /* Save resulting slice */
153  save(fh, ptr+32*idx[i], 32);
154  }
155 }
156 
157 void save_file(FILE *fh, unsigned char *ptr, unsigned long filesz)
158 {
159  unsigned long chunksz;
160 
161  my_srand(filesz);
162 
163  /* Descramble 2 meg blocks for as long as possible, then
164  gradually reduce the window down to 32 bytes (1 slice) */
165  for(chunksz = MAXCHUNK; chunksz >= 32; chunksz >>= 1)
166  while(filesz >= chunksz)
167  {
168  save_chunk(fh, ptr, chunksz);
169  filesz -= chunksz;
170  ptr += chunksz;
171  }
172 
173  /* Save final incomplete slice */
174  if(filesz)
175  save(fh, ptr, filesz);
176 }
177 
178 void write_file(char *filename, unsigned char *ptr, unsigned long sz)
179 {
180  FILE *fh = fopen(filename, "wb");
181  if(fh == NULL)
182  {
183  fprintf(stderr, "Can't open \"%s\".\n", filename);
184  exit(1);
185  }
186  save_file(fh, ptr, sz);
187  fclose(fh);
188 }
189 
190 void dreamcast_descramble(char *src, char *dst)
191 {
192  unsigned char *ptr = NULL;
193  unsigned long sz = 0;
194  FILE *fh;
195 
196  read_file(src, &ptr, &sz);
197 
198  fh = fopen(dst, "wb");
199  if(fh == NULL)
200  {
201  fprintf(stderr, "Can't open \"%s\".\n", dst);
202  exit(1);
203  }
204  if( fwrite(ptr, 1, sz, fh) != sz )
205  {
206  fprintf(stderr, "Write error.\n");
207  exit(1);
208  }
209  fclose(fh);
210  free(ptr);
211 }
212 
213 void scramble(char *src, char *dst)
214 {
215  unsigned char *ptr = NULL;
216  unsigned long sz = 0;
217  FILE *fh;
218 
219  fh = fopen(src, "rb");
220  if(fh == NULL)
221  {
222  fprintf(stderr, "Can't open \"%s\".\n", src);
223  exit(1);
224  }
225  if(fseek(fh, 0, SEEK_END)<0)
226  {
227  fprintf(stderr, "Seek error.\n");
228  exit(1);
229  }
230  sz = ftell(fh);
231  ptr = (unsigned char *) malloc(sz);
232  if( ptr == NULL )
233  {
234  fprintf(stderr, "Out of memory.\n");
235  exit(1);
236  }
237  if(fseek(fh, 0, SEEK_SET)<0)
238  {
239  fprintf(stderr, "Seek error.\n");
240  exit(1);
241  }
242  if( fread(ptr, 1, sz, fh) != sz )
243  {
244  fprintf(stderr, "Read error.\n");
245  exit(1);
246  }
247  fclose(fh);
248 
249  write_file(dst, ptr, sz);
250 
251  free(ptr);
252 }
253 
254 
255 #ifdef STAND_ALONE
256 
257 int main(int argc, char *argv[])
258 {
259  int opt = 0;
260 
261  if(argc > 1 && !strcmp(argv[1], "-d"))
262  opt ++;
263 
264  if(argc != 3+opt)
265  {
266  fprintf(stderr, "Usage: %s [-d] from to\n", argv[0]);
267  exit(1);
268  }
269 
270  if(opt)
271  dreamcast_descramble(argv[2], argv[3]);
272  else
273  scramble(argv[1], argv[2]);
274 
275  return 0;
276 }
277 
278 #endif
void write_file(char *filename, unsigned char *ptr, unsigned long sz)
void read_file(char *filename, unsigned char **ptr, unsigned long *sz)
void dreamcast_descramble(char *src, char *dst)
void load_chunk(FILE *fh, unsigned char *ptr, unsigned long sz)
#define MAXCHUNK
void scramble(char *src, char *dst)
void save(FILE *fh, unsigned char *ptr, unsigned long sz)
int main(int argc, char *argv[])
void save_chunk(FILE *fh, unsigned char *ptr, unsigned long sz)
void load_file(FILE *fh, unsigned char *ptr, unsigned long filesz)
void load(FILE *fh, unsigned char *ptr, unsigned long sz)
void save_file(FILE *fh, unsigned char *ptr, unsigned long filesz)
void my_srand(unsigned int n)
unsigned int my_rand(void)

Generated on Fri Dec 7 2018 19:52:23 for GXemul by doxygen 1.8.13