fix.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. /* $Id$
  2. * MegaZeux
  3. *
  4. * Copyright (C) 1996 Greg Janson
  5. * Copyright (C) 1998 Matthew D. Williams - dbwilli@scsn.net
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License as
  9. * published by the Free Software Foundation; either version 2 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. */
  21. #include <string.h>
  22. #include <stdio.h>
  23. #include <dir.h>
  24. char magic_code[16]="æRëòmMJ·‡²’ˆÞ‘$";
  25. long brd_pos[150];
  26. void skip_layer(FILE *fp,unsigned char xor) {
  27. int xsiz,ysiz;
  28. int x=0,y=0;
  29. int runs;
  30. xsiz=fgetc(fp)^xor;
  31. xsiz+=(fgetc(fp)^xor)<<8;
  32. ysiz=fgetc(fp)^xor;
  33. ysiz+=(fgetc(fp)^xor)<<8;
  34. do {
  35. runs=fgetc(fp)^xor;
  36. if(runs<128) runs=1;
  37. else {
  38. runs^=128;
  39. fgetc(fp);
  40. }
  41. x+=runs;
  42. recap:
  43. if(x>=xsiz) {
  44. x-=xsiz;
  45. y++;
  46. goto recap;
  47. }
  48. } while(y<ysiz);
  49. }
  50. void main(void) {
  51. FILE *fp;
  52. ffblk ff;
  53. int t1;
  54. int t2,t3;
  55. char temp[5]=" \0";
  56. int pro_method;
  57. char password[15]=" ";
  58. int xor;
  59. unsigned int num_boards;
  60. printf("Fixing all version 2.00 .MZX and .MZB files...\n");
  61. //.MZX
  62. if(findfirst("*.MZX",&ff,0)) goto no_mzx;
  63. do {
  64. printf("\t%s... ",ff.ff_name);
  65. fp=fopen(ff.ff_name,"rb+");
  66. if(fp==NULL) {
  67. printf("Error opening file.\n");
  68. continue;
  69. }
  70. fseek(fp,25,SEEK_SET);
  71. pro_method=fgetc(fp);
  72. if(pro_method) fread(password,1,15,fp);
  73. fread(temp,1,3,fp);
  74. if(strcmp(temp,"MZ2")) {
  75. printf("Not a version 2.0? file.\n");
  76. fclose(fp);
  77. continue;
  78. }
  79. //xor code?
  80. if(pro_method) {
  81. for(t1=0;t1<15;t1++) {
  82. password[t1]^=magic_code[t1];
  83. password[t1]-=0x12+pro_method;
  84. password[t1]^=0x8D;
  85. }
  86. for(t1=strlen(password);t1<16;t1++)
  87. password[t1]=0;
  88. xor=85;
  89. for(t1=0;t1<15;t1++) {
  90. //For each byte, roll once to the left and xor in pw byte if it
  91. //is an odd character, or add in pw byte if it is an even character.
  92. xor<<=1;
  93. if(xor>255) xor^=257;//Wraparound from roll
  94. if(t1&1) {
  95. xor+=password[t1];//Add (even byte)
  96. if(xor>255) xor^=257;//Wraparound from add
  97. }
  98. else xor^=password[t1];//XOR (odd byte);
  99. }
  100. //To factor in protection method, add it in and roll one last time
  101. xor+=pro_method;
  102. if(xor>255) xor^=257;
  103. xor<<=1;
  104. if(xor>255) xor^=257;
  105. //Can't be 0-
  106. if(xor==0) xor=86;//(01010110)
  107. }
  108. else xor=0;
  109. //Jump to # of boards
  110. fseek(fp,4234,SEEK_SET);
  111. if(pro_method) fseek(fp,15,SEEK_CUR);
  112. if(!(num_boards=xor^fgetc(fp))) {
  113. num_boards=fgetc(fp)^xor;
  114. num_boards+=(fgetc(fp)^xor)<<8;
  115. fseek(fp,num_boards,SEEK_CUR);
  116. num_boards=fgetc(fp)^xor;
  117. }
  118. //Skip board names
  119. fseek(fp,num_boards*25,SEEK_CUR);
  120. //Get board positions
  121. for(t1=0;t1<num_boards;t1++) {
  122. t3=1;
  123. for(t2=0;t2<4;t2++) {
  124. if(fgetc(fp)!=xor) t3=0;
  125. }
  126. brd_pos[t1]=0;
  127. if(t3) //Deleted board
  128. fseek(fp,4,SEEK_CUR);
  129. else {
  130. for(t2=0;t2<4;t2++)
  131. brd_pos[t1]+=((long)(fgetc(fp)^xor))<<(t2*8);
  132. }
  133. }
  134. //Do each board
  135. for(t1=0;t1<num_boards;t1++) {
  136. if(!brd_pos[t1]) continue;
  137. fseek(fp,brd_pos[t1],SEEK_SET);
  138. fgetc(fp);//Overall size
  139. //Overlay?
  140. if(!(fgetc(fp)^xor)) {
  141. //Yep.
  142. fgetc(fp);
  143. //Skip two layers
  144. skip_layer(fp,xor);
  145. skip_layer(fp,xor);
  146. }
  147. else fseek(fp,-1,SEEK_CUR);
  148. //Skip normal six layers
  149. skip_layer(fp,xor);
  150. skip_layer(fp,xor);
  151. skip_layer(fp,xor);
  152. skip_layer(fp,xor);
  153. skip_layer(fp,xor);
  154. skip_layer(fp,xor);
  155. //In regular info.
  156. fseek(fp,206,SEEK_CUR);
  157. //Write a 00 00 00 00 scroll, and a FF FF FF FF lock
  158. //then a 00 00 00 player lock
  159. for(t2=0;t2<4;t2++)
  160. fputc(xor,fp);
  161. for(t2=0;t2<4;t2++)
  162. fputc(255^xor,fp);
  163. for(t2=0;t2<3;t2++)
  164. fputc(xor,fp);
  165. //Next board!
  166. printf("*");
  167. }
  168. fclose(fp);
  169. //Next file!
  170. printf(" Done!\n");
  171. } while(!findnext(&ff));
  172. no_mzx:
  173. //.MZB
  174. if(findfirst("*.MZB",&ff,0)) return;
  175. do {
  176. printf("\t%s... ",ff.ff_name);
  177. fp=fopen(ff.ff_name,"rb+");
  178. if(fp==NULL) {
  179. printf("Error opening file.\n");
  180. continue;
  181. }
  182. fread(temp,1,4,fp);
  183. if(strcmp(temp,"\xFFMB2")) {
  184. printf("Not a version 2.0? file.\n");
  185. fclose(fp);
  186. continue;
  187. }
  188. fgetc(fp);//Overall size
  189. //Overlay?
  190. if(!fgetc(fp)) {
  191. //Yep.
  192. fgetc(fp);
  193. //Skip two layers
  194. skip_layer(fp,0);
  195. skip_layer(fp,0);
  196. }
  197. else fseek(fp,-1,SEEK_CUR);
  198. //Skip normal six layers
  199. skip_layer(fp,0);
  200. skip_layer(fp,0);
  201. skip_layer(fp,0);
  202. skip_layer(fp,0);
  203. skip_layer(fp,0);
  204. skip_layer(fp,0);
  205. //In regular info.
  206. fseek(fp,206,SEEK_CUR);
  207. //Write a 00 00 00 00 scroll, and a FF FF FF FF lock
  208. //then a 00 00 00 player lock
  209. for(t2=0;t2<4;t2++)
  210. fputc(0,fp);
  211. for(t2=0;t2<4;t2++)
  212. fputc(255,fp);
  213. for(t2=0;t2<3;t2++)
  214. fputc(0,fp);
  215. fclose(fp);
  216. //Next file!
  217. printf("Done!\n");
  218. } while(!findnext(&ff));
  219. //Done!
  220. printf("\nDone with all files.\n\n");
  221. }