ff7tk  0.02
Toolkit for making FF7 Tools
FF7Save.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // copyright 2012 -2016 Chris Rizzitello <sithlord48@gmail.com> //
3 // //
4 // This file is part of FF7tk //
5 // //
6 // FF7tk is free software: you can redistribute it and/or modify //
7 // it under the terms of the GNU General Public License as published by //
8 // the Free Software Foundation, either version 3 of the License, or //
9 // (at your option) any later version. //
10 // //
11 // FF7tk is distributed in the hope that it will be useful, //
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of //
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
14 // GNU General Public License for more details. //
15 /****************************************************************************/
16 #include <QDebug>
17 #include "FF7Save.h"
18 #include <QObject>
19 #include <QFile>
20 #include <QDataStream>
21 #include <QTextStream>
22 #include <QCryptographicHash>
23 //Includes From OpenSSL
24 #if defined(OPENSSL) && (OPENSSL == 1)
25 #include <openssl/evp.h>
26 #include <openssl/hmac.h>
27 #include <openssl/aes.h>
28 #else
29 #define OPENSSL 0
30 #endif
31 // This Class should contain NO Gui Parts
32 
34 {
35  fileHasChanged = false;
36  for(int i=0;i<15;i++){slotChanged[i]=false;}
37  SG_SIZE=0;
38  SG_HEADER=0;
39  SG_FOOTER=0;
40  SG_DATA_SIZE=0;
43  SG_SLOT_SIZE=0;
45  SG_TYPE="";
46  file_headerp=0;
47  file_footerp=0;
48  memcpy(&buffer_slot,&default_save,0x10F4);
49 }
50 bool FF7Save::loadFile(const QString &fileName)
51 {
52  // Return true if File Loaded and false if file not loaded.
53  if(fileName.isEmpty()){return false;}// bail on empty string.
54  QFile file(fileName);
55  if(!file.open(QIODevice::ReadOnly)){return false;}
56  int file_size = file.size();
57  /*~~~~~~~~~~~~~~~~~~~~~~~~~~Set File Type Vars ~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
58  //decide the file type
59  if((file_size == FF7_PC_SAVE_GAME_SIZE)&& (file.peek(PC_SAVE_GAME_FILE_ID.length()))==PC_SAVE_GAME_FILE_ID){setType("PC");}
60  else if((file_size == FF7_MC_SAVE_GAME_SIZE)&& (file.peek(MC_SAVE_GAME_FILE_ID.length()))==MC_SAVE_GAME_FILE_ID){setType("MC");}
61  else if((file_size == FF7_PSV_SAVE_GAME_SIZE)&& (file.peek(PSV_SAVE_GAME_FILE_ID.length()))==PSV_SAVE_GAME_FILE_ID){setType("PSV");}
62  else if((file_size ==FF7_PSP_SAVE_GAME_SIZE)&& (file.peek(PSP_SAVE_GAME_FILE_ID.length()))==PSP_SAVE_GAME_FILE_ID){setType("PSP");}
63  else if((file_size ==FF7_VGS_SAVE_GAME_SIZE)&& (file.peek(VGS_SAVE_GAME_FILE_ID.length()))==VGS_SAVE_GAME_FILE_ID){setType("VGS");}
64  else if((file_size ==FF7_DEX_SAVE_GAME_SIZE)&& (file.peek(DEX_SAVE_GAME_FILE_ID.length()))==DEX_SAVE_GAME_FILE_ID){setType("DEX");}
65  else if(file_size % FF7_PSX_SAVE_GAME_SIZE ==0) {setType("PSX");}
66  else{return false;}
67  /*~~~~~~~~~~Start Load~~~~~~~~~~*/
68  setFileHeader(file.read(SG_HEADER));
69  for (int i=0;i<SG_SLOT_NUMBER;i++)
70  {
71  setSlotHeader(i,file.read(SG_SLOT_HEADER));
72  setSlotFF7Data(i,file.read(SG_DATA_SIZE));
73  setSlotFooter(i,file.read(SG_SLOT_FOOTER));
74  }
75  setFileFooter(file.read(SG_FOOTER));
76  /*~~~~~~~End Load~~~~~~~~~~~~~~*/
77  if (SG_TYPE == "PC")
78  {
79  for(int i=0;i<15;i++)
80  {
81  if(slot[i].checksum != 0x0000 && slot[i].checksum != 0x4D1D){SG_Region_String[i]= QString("BASCUS-94163FF7-S%1").arg(QString::number(i+1),2,QChar('0'));} else {SG_Region_String[i].clear();}
82  }
83  }
84 
85  else if (SG_TYPE == "PSX")
86  {
87  if((fileName.contains("00867")) || (fileName.contains("00869")) || (fileName.contains("00900")) ||
88  (fileName.contains("94163")) || (fileName.contains("00700")) || (fileName.contains("01057")) ||
89  (fileName.contains("00868")))
90  {
91  QString string;
92  string = fileName.mid(fileName.lastIndexOf("/")+1,fileName.lastIndexOf(".")-1-fileName.lastIndexOf("/"));
93  SG_Region_String[0]= string.mid(string.lastIndexOf("BA")-1,string.lastIndexOf("FF7-S")+8);
94  }
95  else {SG_Region_String[0] = file.fileName();}
96  for(int i=1;i<14;i++){clearSlot(i);}
97  }
98 
99  else if (SG_TYPE =="PSV")
100  {
101  file.seek(0x64);
102  SG_Region_String[0] = QString(file.read(19));
103  for(int i=1;i<14;i++){clearSlot(i);}
104  }
105 
106  else if (SG_TYPE == "MC" || SG_TYPE =="PSP" || SG_TYPE == "VGS" ||SG_TYPE=="DEX")
107  {
108  QByteArray mc_header;
109  int offset = 0;//raw psx card types
110  if(SG_TYPE =="PSP"){offset = 0x80;}
111  if(SG_TYPE =="VGS"){offset = 0x40;}
112  if(SG_TYPE =="DEX"){offset = 0xF40;}
113  file.seek(offset);
114  mc_header = file.read(SG_HEADER);
115  for(int i=0; i<15;i++)
116  {
117  int index = (128*i) +138;
118  SG_Region_String[i]=QString(mc_header.mid(index,19));\
119  }
120 
121  }
122  else{return false;}
123  file.close();
125  setFileModified(false,0);
126  return true;
127 }
128 QByteArray FF7Save::fileHeader(void)
129 {
130  QByteArray temp;
131  if(SG_HEADER > 0) {temp.setRawData(reinterpret_cast<char *>(file_headerp),SG_HEADER);}
132  return temp;
133 }
134 
135 bool FF7Save::setFileHeader(QByteArray data)
136 {
137  if(data.size() != SG_HEADER){return false;}
138  else
139  {
140  if(SG_HEADER > 0){memcpy(file_headerp,data,SG_HEADER);}
141  return true;
142  }
143 
144 }
145 
146 QByteArray FF7Save::slotHeader(int s)
147 {
148  QByteArray temp;
149  temp.setRawData(reinterpret_cast<char *>(&hf[s].sl_header),SG_SLOT_HEADER);
150  return temp;
151 }
152 bool FF7Save::setSlotHeader(int s, QByteArray data)
153 {
154  if(s<0 || s>14){return false;}
155  if(data.size()!=SG_SLOT_HEADER){return false;}
156  memcpy(&hf[s].sl_header,data,SG_SLOT_HEADER);
157  setFileModified(true,s);
158  return true;
159 }
160 
161 QByteArray FF7Save::fileFooter(void)
162 {
163  QByteArray temp;
164  if(SG_FOOTER > 0){temp.setRawData(reinterpret_cast<char *>(file_footerp),SG_FOOTER);}
165  return temp;
166 }
167 
168 bool FF7Save::setFileFooter(QByteArray data)
169 {
170  if(data.size() != SG_FOOTER){return false;}
171  else
172  {
173  if(SG_FOOTER > 0){memcpy(file_footerp,data,SG_FOOTER);}
174  return true;
175  }
176 }
177 QByteArray FF7Save::slotFooter(int s)
178 {
179  QByteArray temp;
180  temp.setRawData(reinterpret_cast<char *>(&hf[s].sl_footer),SG_SLOT_FOOTER);
181  return temp;
182 }
183 bool FF7Save::setSlotFooter(int s, QByteArray data)
184 {
185  if(s<0 || s>14){return false;}
186  if(data.size()!=SG_SLOT_FOOTER){return false;}
187  memcpy(&hf[s].sl_footer,data,SG_SLOT_FOOTER);
188  setFileModified(true,s);
189  return true;
190 }
191 QByteArray FF7Save::slotPsxRawData(int s)
192 {
193  if(filename.isEmpty()){return QByteArray("\x00");}
194  else if (type() == "PC"){return QByteArray("\x00");}
195  else if ((type() == "PSV") || (type() == "PSX"))
196  {
197  QFile file(fileName());
198  if(!file.open(QIODevice::ReadOnly)){return QByteArray("\x00");}
199  QByteArray temp(file.readAll());
200  if(type()=="PSV"){temp.remove(0,0x84);}
201  file.close();
202  return temp;
203  }
204  else
205  {
206  QByteArray temp;
207  int blocks = psx_block_size(s);
208  for(int i=0; i<blocks;i++)
209  {
210  temp.append(slotHeader(s));
211  temp.append(slotFF7Data(s));
212  temp.append(slotFooter(s));
213  s= psx_block_next(s);
214  }
215  return temp;
216  }
217 }
218 bool FF7Save::setSlotPsxRawData(int s, QByteArray data)
219 {
220  if(s<0 || s>14){return false;}
221  int blocks = data.length()/0x2000;
222 
223  for(int i=0; i< blocks ; i++)
224  {//done once for each block
225  int offset = (i*0x2000);
226  int next = psx_block_next(s);
227  setSlotHeader(s,data.mid(offset,0x0200));
228  offset +=0x0200;
229  setSlotFF7Data(s,data.mid(offset,0x10F4));
230  offset +=0x10F4;
231  setSlotFooter(s,data.mid(offset,0xD0C));
232  s=next;
233  }
234  setFileModified(true,s);
235  return true;
236 }
237 bool FF7Save::saveFile(const QString &fileName)
238 {
239  if(fileName.isEmpty()){return false;}
240  //fix our headers before saving
241  if(type() =="PC"){/*PC Header Should be Fixed By Host*/}
242  else if(type() == "PSX"){fix_psx_header(0);}
243  else if(type() =="PSV"){fix_psv_header(0);}
244  else{fix_vmc_header();}
245  checksumSlots();
246  // write the file
247  QFile file(fileName);
248  if(!file.open(QIODevice::ReadWrite)){return false;}
249  file.write(fileHeader(),SG_HEADER);
250  for(int si=0;si<SG_SLOT_NUMBER;si++)
251  {
252  file.write(slotHeader(si),SG_SLOT_HEADER);
253  file.write(slotFF7Data(si),SG_DATA_SIZE);
254  file.write(slotFooter(si),SG_SLOT_FOOTER);
255  }
256  file.write(fileFooter(),SG_FOOTER);
257  file.close();
259  if(type()==("PC"))
260  {
261  QString metadata =fileName;
262  metadata.chop(metadata.length()-metadata.lastIndexOf("/"));
263  metadata.append("/metadata.xml");
264  if((QFile(metadata).exists())){fixMetaData();}
265  }
266  setFileModified(false,0);
267  return true;
268 }
269 bool FF7Save::exportFile(const QString &fileName,QString newType,int s)
270 {
271  if(fileName.isEmpty()){return false;}
272  else
273  {
274  if(newType =="PC"){return exportPC(fileName);}
275  else if(newType =="PSX"){return exportPSX(s,fileName);}
276  else if(newType =="MC"){return exportVMC(fileName);}
277  else if(newType =="VGS"){return exportVGS(fileName);}
278  else if(newType =="DEX"){return exportDEX(fileName);}
279  else{return false;}
280  //else if(newType =="PSV"){return false;}
281  //else if(newType =="VMP"){return false;}
282  }
283 }
284 
285 bool FF7Save::exportPC(const QString &fileName)
286 {
287  if(fileName.isEmpty()){return false;}
288  QString prev_type = SG_TYPE;
289  QString prev_fileName = filename;
290  if(SG_TYPE !="PC")
291  {
292  for(int i=0;i<15;i++){if(isFF7(i)){setControlMode(i,CONTROL_NORMAL);}}
293  setType("PC");
294  // Add File Header
295  for(int i=0;i<9;i++){file_header_pc[i]= PC_SAVE_GAME_FILE_HEADER[i];}
296  fix_pc_bytemask(0);//set first slot to 0
297  }
298  for(int i=0;i<15;i++)//clean up saves and fix time for Pal Saves.
299  {
300  if (isNTSC(i)){/*NTSC FF7 DATA.*/}
301  else if(isPAL(i))
302  {//PAL FF7 DATA , FIX PLAY TIME THEN SAVE
303  slot[i].time = (slot[i].time*1.2);
304  slot[i].desc.time = slot[i].time;
305  }
306  else{clearSlot(i);}
307  }
308  if(saveFile(fileName))
309  {
310  setType(prev_type);
311  setFileModified(false,0);
312  filename=prev_fileName;
313  return true;
314  }
315  else
316  {
317  setType(prev_type);
318  filename = prev_fileName;
319  return false;
320  }
321 }
322 bool FF7Save::exportPSX(int s,const QString &fileName)
323 {
324  if(fileName.isEmpty()){return false;}
325  int blocks=1;
326  QString prev_type = SG_TYPE;
327  QString prev_fileName=filename;
328 
329  if(SG_TYPE != "PSX")
330  {
332  else{blocks = psx_block_size(s);}
333  setType("PSX");
334  }
335  if(isFF7(s))
336  {
337  if(fileName.endsWith("S01")){for(int i=0;i<256;i++) {hf[s].sl_header[i] = PSX_SAVE_GAME_FILE_HEADER_S01[i];}}
338  else if(fileName.endsWith("S02")){for(int i=0;i<256;i++){hf[s].sl_header[i] = PSX_SAVE_GAME_FILE_HEADER_S02[i];}}
339  else if(fileName.endsWith("S03")){for(int i=0;i<256;i++){hf[s].sl_header[i] = PSX_SAVE_GAME_FILE_HEADER_S03[i];}}
340  else if(fileName.endsWith("S04")){for(int i=0;i<256;i++){hf[s].sl_header[i] = PSX_SAVE_GAME_FILE_HEADER_S04[i];}}
341  else if(fileName.endsWith("S05")){for(int i=0;i<256;i++){hf[s].sl_header[i] = PSX_SAVE_GAME_FILE_HEADER_S05[i];}}
342  else if(fileName.endsWith("S06")){for(int i=0;i<256;i++){hf[s].sl_header[i] = PSX_SAVE_GAME_FILE_HEADER_S06[i];}}
343  else if(fileName.endsWith("S07")){for(int i=0;i<256;i++){hf[s].sl_header[i] = PSX_SAVE_GAME_FILE_HEADER_S07[i];}}
344  else if(fileName.endsWith("S08")){for(int i=0;i<256;i++){hf[s].sl_header[i] = PSX_SAVE_GAME_FILE_HEADER_S08[i];}}
345  else if(fileName.endsWith("S09")){for(int i=0;i<256;i++){hf[s].sl_header[i] = PSX_SAVE_GAME_FILE_HEADER_S09[i];}}
346  else if(fileName.endsWith("S10")){for(int i=0;i<256;i++){hf[s].sl_header[i] = PSX_SAVE_GAME_FILE_HEADER_S10[i];}}
347  else if(fileName.endsWith("S11")){for(int i=0;i<256;i++){hf[s].sl_header[i] = PSX_SAVE_GAME_FILE_HEADER_S11[i];}}
348  else if(fileName.endsWith("S12")){for(int i=0;i<256;i++){hf[s].sl_header[i] = PSX_SAVE_GAME_FILE_HEADER_S12[i];}}
349  else if(fileName.endsWith("S13")){for(int i=0;i<256;i++){hf[s].sl_header[i] = PSX_SAVE_GAME_FILE_HEADER_S13[i];}}
350  else if(fileName.endsWith("S14")){for(int i=0;i<256;i++){hf[s].sl_header[i] = PSX_SAVE_GAME_FILE_HEADER_S14[i];}}
351  else if(fileName.endsWith("S15")){for(int i=0;i<256;i++){hf[s].sl_header[i] = PSX_SAVE_GAME_FILE_HEADER_S15[i];}}
352  else{/*user ERROR*/}
353  for(int i=0; i<SG_SLOT_FOOTER;i++){hf[s].sl_footer[i] =0x00;} //CLEAN FOOTER
354  fix_psx_header(s);//only fix time for FF7 Slots.
355  checksumSlots();
356  }
357  QFile file(fileName);
358  if(!file.open(QIODevice::ReadWrite)){return false;}
359  file.write(fileHeader(),SG_HEADER);
360  for(int i=0;i<blocks;i++)
361  {
362  int next = psx_block_next(s);
363  file.write(slotHeader(s),SG_SLOT_HEADER);
364  file.write(slotFF7Data(s),SG_DATA_SIZE);
365  file.write(slotFooter(s),SG_SLOT_FOOTER);
366  s=next;
367  }
368  file.write(fileFooter(),SG_FOOTER);
369  file.close();
370  setType(prev_type);
371  filename=prev_fileName;
372  return true;
373 }
374 
375 bool FF7Save::exportVMC(const QString &fileName)
376 {
377  if(fileName.isEmpty()){return false;}
378  QString prev_type = SG_TYPE;
379  QString prev_fileName = filename;
380  if(SG_TYPE != "MC")
381  {
382  for(int i=0;i<15;i++){if(isFF7(i)){setControlMode(i,CONTROL_NORMAL);}}
383  setType("MC");
384  //Check if from another kind of VMC and copy the header
385  if(prev_type =="PSP"){for(int i=0;i<0x2000;i++){file_headerp[i] = file_header_psp[i+0x080];}}
386  if(prev_type =="VGS"){for(int i=0;i<0x2000;i++){file_headerp[i] = file_header_vgs[i+0x040];}}
387  if(prev_type =="DEX"){for(int i=0;i<0x2000;i++){file_headerp[i] = file_header_dex[i+0xF40];}}
388  }
389  fix_vmc_header();
390  if(saveFile(fileName))
391  {
392  setType(prev_type);
393  filename=prev_fileName;
394  return true;
395  }
396  else
397  {
398  setType(prev_type);
399  filename=prev_fileName;
400  return false;
401  }
402 }
403 bool FF7Save::exportVGS(const QString &fileName)
404 {
405  if(fileName.isEmpty()){return false;}
406  QString prev_type = SG_TYPE;
407  QString prev_fileName = filename;
408  if(prev_type != "VGS")
409  {
410  for(int i=0;i<15;i++){if(isFF7(i)){setControlMode(i,CONTROL_NORMAL);}}
411  setType("VGS");//fill the Header With The Needed Default
412  file_header_vgs[0] =0x56;
413  file_header_vgs[1] =0x67;
414  file_header_vgs[2] =0x73;
415  file_header_vgs[3] =0x4D;
416  file_header_vgs[4] =0x01;
417  file_header_vgs[8] =0x01;
418  file_header_vgs[12] =0x01;
419  //Check if from another kind of VMC and copy the header
420  if(prev_type =="PSP"){for(int i=0;i<0x2040;i++){file_headerp[i] = file_header_psp[i+0x040];}}
421  if(prev_type =="DEX"){for(int i=0;i<0x2040;i++){file_headerp[i] = file_header_dex[i+0xF00];}}
422  if(prev_type =="MC"){for(int i=0x40;i<0x2040;i++){file_headerp[i] = file_header_mc[i-0x40];}}
423  }
424  fix_vmc_header();
425 
426  if(saveFile(fileName))
427  {
428  setType(prev_type);
429  filename=prev_fileName;
430  return true;
431  }
432  else
433  {
434  setType(prev_type);
435  filename=prev_fileName;
436  return false;
437  }
438 }
439 bool FF7Save::exportDEX(const QString &fileName)
440 {
441  if(fileName.isEmpty()){return false;}
442  QString prev_type = SG_TYPE;
443  QString prev_fileName = filename;
444  if(SG_TYPE != "DEX")
445  {
446  for(int i=0;i<15;i++){if(isFF7(i)){setControlMode(i,CONTROL_NORMAL);}}
447  setType("DEX");
448  //default header..
449  file_header_dex[0]=0x31;
450  file_header_dex[1]=0x32;
451  file_header_dex[2]=0x33;
452  file_header_dex[3]=0x2D;
453  file_header_dex[4]=0x34;
454  file_header_dex[5]=0x35;
455  file_header_dex[6]=0x36;
456  file_header_dex[7]=0x2D;
457  file_header_dex[8]=0x53;
458  file_header_dex[9]=0x54;
459  file_header_dex[10]=0x44;
460  file_header_dex[18]=0x01;
461  file_header_dex[20]=0x01;
462  file_header_dex[21]=0x4D;
463  file_header_dex[22]=0x51;
464  for(int i=0x17;i<0x25;i++){file_header_dex[i]=0xA0;}
465  file_header_dex[38]=0xFF;
466  //Check if from another kind of VMC and copy the header
467  if(prev_type =="MC"){for(int i=0xF40;i<0x2F40;i++){file_headerp[i] = file_header_mc[i-0xF40];}}
468  if(prev_type =="VGS"){for(int i=0xF00;i<0x2F40;i++){file_headerp[i] = file_header_vgs[i-0xF00];}}
469  if(prev_type =="PSP"){for(int i=0xEC0;i<0x2F40;i++){file_headerp[i] = file_header_psp[i-0xEC0];}}
470  }
471  fix_vmc_header();
472  if(saveFile(fileName))
473  {
474  setType(prev_type);
475  filename=prev_fileName;
476  return true;
477  }
478  else
479  {
480  setType(prev_type);
481  filename=prev_fileName;
482  return false;
483  }
484 }
485 void FF7Save::importSlot(int s, QString fileName,int fileSlot)
486 {
487  QString inType="";
488  int offset=0;
489  if(s<0 || s>14){return;}
490  if(fileName.isEmpty()){return;}
491  QFile file(fileName);
492  if(!file.open(QIODevice::ReadOnly)){return;}
493  int file_size = file.size();
494  /*~~~~~~~~~~~~~~~~~~~~~~~~~~Set File Type Vars ~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
495  //decide the file type
496 
497  if((file_size == FF7_PC_SAVE_GAME_SIZE)&& (file.peek(PC_SAVE_GAME_FILE_ID.length()))==PC_SAVE_GAME_FILE_ID)
498  {
499  inType="PC";
500  offset = FF7_PC_SAVE_GAME_HEADER;
502  }
503  else if((file_size == FF7_PSX_SAVE_GAME_SIZE)&& (file.peek(PSX_SAVE_GAME_FILE_ID.length()))==PSX_SAVE_GAME_FILE_ID)
504  {
505  inType="PSX";
507  }
508  else if((file_size == FF7_MC_SAVE_GAME_SIZE)&& (file.peek(MC_SAVE_GAME_FILE_ID.length()))==MC_SAVE_GAME_FILE_ID)
509  {
510  inType="MC";
512  offset += ((FF7_MC_SAVE_GAME_SLOT_SIZE) *fileSlot);
513  }
514  else if((file_size == FF7_PSV_SAVE_GAME_SIZE)&& (file.peek(PSV_SAVE_GAME_FILE_ID.length()))==PSV_SAVE_GAME_FILE_ID)
515  {
516  inType="PSV";
518  }
519  else if((file_size ==FF7_PSP_SAVE_GAME_SIZE)&& (file.peek(PSP_SAVE_GAME_FILE_ID.length()))==PSP_SAVE_GAME_FILE_ID)
520  {
521  inType="PSP";
523  offset += ((FF7_PSP_SAVE_GAME_SLOT_SIZE) *fileSlot);
524  }
525  else if((file_size ==FF7_VGS_SAVE_GAME_SIZE)&& (file.peek(VGS_SAVE_GAME_FILE_ID.length()))==VGS_SAVE_GAME_FILE_ID)
526  {
527  inType="VGS";
529  offset += ((FF7_VGS_SAVE_GAME_SLOT_SIZE) *fileSlot);
530  }
531  else if((file_size ==FF7_DEX_SAVE_GAME_SIZE)&& (file.peek(DEX_SAVE_GAME_FILE_ID.length()))==DEX_SAVE_GAME_FILE_ID)
532  {
533  inType="DEX";
535  offset += ((FF7_DEX_SAVE_GAME_SLOT_SIZE) *fileSlot);
536  }
537  else{file.close();return;}
538  file.seek(offset);
539  setSlotFF7Data(s,file.read(0x10F4));
540  /*~~~~~~~End Load~~~~~~~~~~~~~~*/
541 
542  /*~~~~~Set Region Data~~~~~~~~~*/
543  if (inType == "PC")
544  {
545  if(slot[s].checksum != 0x0000 && slot[s].checksum != 0x4D1D)
546  {
547  setRegion(s,QString("BASCUS-94163FF7-S%1").arg(QString::number(s).toInt(),2,10,QChar('0').toUpper()));
548  }
549  else{setRegion(s,"");}
550  }
551  else if (inType == "MC" || inType =="PSP" || inType == "VGS" ||inType=="DEX")
552  {
553 
554  QByteArray mc_header;
555  offset = 0;//raw psx card types
556  int headerSize=FF7_MC_SAVE_GAME_HEADER;
557  if(inType =="PSP"){offset = 0x80; headerSize=FF7_PSP_SAVE_GAME_HEADER;}
558  if(inType =="VGS"){offset = 0x40; headerSize=FF7_VGS_SAVE_GAME_HEADER;}
559  if(inType =="DEX"){offset = 0xF40;headerSize=FF7_DEX_SAVE_GAME_HEADER;}
560  file.seek(offset);
561  mc_header = file.read(headerSize);
562  int index=0;
563  index = (128*fileSlot) +138;
564  setRegion(s,QString(mc_header.mid(index,19)));
565  }
566  else if (inType == "PSX")
567  {
568  if((file.fileName().contains("00867")) || (file.fileName().contains("00869")) || (file.fileName().contains("00900")) ||
569  (file.fileName().contains("94163")) || (file.fileName().contains("00700")) || (file.fileName().contains("01057")) || (file.fileName().contains("00868")))
570  {
571  QString string;
572  string = file.fileName().mid(file.fileName().lastIndexOf("/")+1,file.fileName().lastIndexOf(".")-1-file.fileName().lastIndexOf("/"));
573  setRegion(s,string.mid(string.lastIndexOf("BA")-1,string.lastIndexOf("FF7-S")+8));
574  }
575  else {setRegion(s,"");}
576  }
577  else if (inType=="PSV")
578  {
579  file.seek(0x64);
580  setRegion(s,QString(file.read(19)));
581  }
582  else
583  {//Unknown or Unspecified Type Abort.
584  file.close();
585  return;
586  }
587  file.close();
588  setFileModified(true,s);
589 }
590 
591 void FF7Save::clearSlot(int rmslot)
592 {
593  if(isSlotEmpty(rmslot)){return;}
594  QByteArray temp;
595  temp.fill(0x00,0x10f4);
596  memcpy(hf[rmslot].sl_header,temp,SG_SLOT_HEADER);// clear the header..
597  memcpy(&slot[rmslot],temp,0x10f4);
598  memcpy(hf[rmslot].sl_footer,temp,SG_SLOT_FOOTER);// clear the footer..
599  SG_Region_String[rmslot].clear();
600  if(SG_TYPE =="MC" || SG_TYPE =="PSP" || SG_TYPE =="VGS" || SG_TYPE =="DEX")
601  {//clean the mem card header if needed.
602  int index = (128+(128*rmslot));
603  if (SG_TYPE == "PSP"){index +=0x80;}
604  else if (SG_TYPE == "VGS"){index +=0x40;}
605  else if (SG_TYPE == "DEX"){index +=0xF40;}
606  temp.resize(128);
607  temp.fill(0x00);
608  temp[0]=0xA0;
609  temp[8]=0xFF;
610  temp[9]=0xFF;
611  temp[0x7F]=0xA0;
612  memcpy(&file_headerp[index],temp,128);
613  setFileModified(true,rmslot);
614  }
615 }
616 bool FF7Save::exportCharacter(int s,int char_num,QString fileName)
617 {
618  QFile file(fileName);
619  if(!file.open(QIODevice::ReadWrite)){return false;}
620  file.write(rawCharacterData(s,char_num),132);
621  file.close();
622  return true;
623 }
624 void FF7Save::importCharacter(int s,int char_num,QByteArray new_char){memcpy(&slot[s].chars[char_num],new_char.data(),132);setFileModified(true,s);}
625 
627 {
628  for (int i=0; i<SG_SLOT_NUMBER;i++)
629  {
630  if(isFF7(i))
631  {
632  quint16 checksum = ff7Checksum(i);
633  if(checksum == 0x4D1D){slot[i].checksum=0x0000; }
634  else{slot[i].checksum = checksum;}
635  }
636  }
637 
638 }
639 quint16 FF7Save::ff7Checksum(int s)
640 {
641  QByteArray data = slotFF7Data(s).mid(4,4336);
642  int i = 0;
643  quint16 r = 0xFFFF, len =4336, pbit = 0x8000;
644  while(len--)
645  {
646  int t=data.at(i++);
647  r ^= t << 8;
648  for(int d=0;d<8;d++)
649  {
650  if( r & pbit ){r = ( r << 1 ) ^ 0x1021;}
651  else{ r <<= 1;}
652  }
653  r &= ( 1 << 16 ) - 1;
654  }
655  return ((r^0xFFFF)&0xFFFF);
656 }
657 
658 quint16 FF7Save::itemDecode( quint16 itemraw )
659 {
660  quint16 item;
661  #ifdef Q_BYTE_ORDER
662  #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
663  item = itemraw;
664  #elif Q_BYTE_ORDER == Q_BIG_ENDIAN
665  item = ((itemraw & 0xFF) << 8) | ((itemraw >> 8) & 0xFF);
666  #else
667  int one = 1;
668  if (*(char *)&one){
669  /******************************************************************************************/
670  /* Little-Endian (Do Nothing, No Change) */
671  /* ITEMRAW: */
672  /* Itemraw Format: QQQQQQQXXXXXXXXX */
673  /* ITEM: */
674  /* Item Format: QQQQQQQXXXXXXXXX */
675  /******************************************************************************************/
676  item = itemraw;
677  } else {
678  /***********************************--*****************************************************/
679  /* Big-Endian (Do things, Format Change) */
680  /* ITEMRAW: */
681  /* Itemraw Format: XXXXXXXXQQQQQQQX */
682  /* ITEM: */
683  /* Left Shift&Mask itemraw 8bits: QQQQQQQX00000000 & 1111111100000000 = QQQQQQQX00000000 */
684  /* Right Shift&Mask itemraw 8bits: 00000000XXXXXXXX & 0000000011111111 = 00000000XXXXXXXX */
685  /* Then OR them: QQQQQQQX00000000 | 00000000XXXXXXXX = QQQQQQQXXXXXXXXX */
686  /* Item Format: QQQQQQQXXXXXXXXX */
687  /******************************************************************************************/
688  item = ((itemraw & 0xFF) << 8) | ((itemraw >> 8) & 0xFF);
689  }
690  #endif
691  #else
692  int one = 1;
693  if (*(char *)&one){
694  item = itemraw;
695  } else {
696  item = ((itemraw & 0xFF) << 8) | ((itemraw >> 8) & 0xFF);
697  }
698  #endif
699 
700  return item;
701 }
702 quint16 FF7Save::itemEncode( quint16 id, quint8 qty )
703 {
704  quint16 item,itemraw;
705  #ifdef Q_BYTE_ORDER
706  #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
707  item = ((qty << 9) & 0xFE00) | (id & 0x1FF);
708  itemraw = item;
709  #elif Q_BYTE_ORDER == Q_BIG_ENDIAN
710  item = ((qty << 9) & 0xFE00) | (id & 0x1FF);
711  itemraw = ((item & 0xFF) << 8) | ((item >> 8) & 0xFF);
712  #else
713  int one = 1;
714  if (*(char *)&one) {
715  /******************************************************************************************/
716  /* Little-Endian */
717  /* ITEM: */
718  /* Item Format: QQQQQQQXXXXXXXXX */
719  /* Left Shift&Mask qty 9bits: QQQQQQQ000000000 & 1111111000000000 = QQQQQQQ000000000 */
720  /* Right Mask id 9bits: XXXXXXXXX & 0000000111111111 = 0000000XXXXXXXXX */
721  /* Then OR them: QQQQQQQ000000000 | 0000000XXXXXXXXX = QQQQQQQXXXXXXXXX */
722  /* ITEMRAW: */
723  /* Itemraw Format: QQQQQQQXXXXXXXXX */
724  /******************************************************************************************/
725  item = ((qty << 9) & 0xFE00) | (id & 0x1FF);
726  itemraw = item;
727  } else {
728  /******************************************************************************************/
729  /* Big-Endian */
730  /* ITEM: */
731  /* Left Shift&Mask qty 9bits: QQQQQQQ000000000 & 1111111000000000 = QQQQQQQ000000000 */
732  /* Right Mask id 9bits: 0000000XXXXXXXXX & 0000000111111111 = 0000000XXXXXXXXX */
733  /* Then OR them: QQQQQQQ000000000 | 0000000XXXXXXXXX = QQQQQQQXXXXXXXXX */
734  /* Item Format: QQQQQQQXXXXXXXXX */
735  /* ITEMRAW: */
736  /* Left Shift&Mask item 8bits: QQQQQQQX00000000 & 1111111100000000 = QQQQQQQX00000000 */
737  /* Right Shift&Mask item 8bits: 00000000XXXXXXXX & 0000000011111111 = 00000000XXXXXXXX */
738  /* Then OR them: QQQQQQQX00000000 | 00000000XXXXXXXX = QQQQQQQXXXXXXXXX */
739  /* Itemraw Format: XXXXXXXXQQQQQQQX */
740  /******************************************************************************************/
741  item = ((qty << 9) & 0xFE00) | (id & 0x1FF);
742  itemraw = ((item & 0xFF) << 8) | ((item >> 8) & 0xFF);
743  }
744  #endif
745  #else
746  int one = 1;
747  if (*(char *)&one)
748  {
749  item = ((qty << 9) & 0xFE00) | (id & 0x1FF);
750  itemraw = item;
751  }
752  else
753  {
754  item = ((qty << 9) & 0xFE00) | (id & 0x1FF);
755  itemraw = ((item & 0xFF) << 8) | ((item >> 8) & 0xFF);
756  }
757  #endif
758 
759  return itemraw;
760 }
761 void FF7Save::setItem(int s,int item_num,quint16 rawitem)
762 {
763  if(region(s).contains("SLPS-00700") && (itemQty(rawitem)>99) && (itemId(rawitem != 0x1FF))){rawitem = itemEncode(itemId(rawitem),99);}
764  //Item Qty over 99 on SLPS-00700 Causes an Error Durring Battle and break all items.
765  //Above Is to Check for and fix, since im sure no one wants to lose all their items.
766  slot[s].items[item_num]=rawitem;
767  setFileModified(true,s);
768 }
769 void FF7Save::setItem(int s,int item_num,quint16 new_id,quint8 new_qty)
770 {
771  if(region(s).contains("SLPS-00700") &&(new_qty>99) &&(new_id != 0x1FF)){new_qty = 99;}
772  //Item Qty over 99 on SLPS-00700 Causes an Error Durring Battle and break all items.
773  //Above Is to Check for and fix, since im sure no one wants to lose all their items.
774  slot[s].items[item_num]= itemEncode(new_id,new_qty);
775  setFileModified(true,s);
776 }
777 
778 quint16 FF7Save::item(int s,int item_num){return slot[s].items[item_num];}
779 QList<quint16> FF7Save::items(int s)
780 {
781  QList<quint16> item_list;
782  for (int i=0;i<320;i++){item_list.append(slot[s].items[i]);}
783  return item_list;
784 }
785 
786 void FF7Save::setItems(int s,QList<quint16> items)
787 {
788  if(region(s).contains("SLPS-00700"))
789  {
790  for(int i=0;i<320;i++)
791  {
792  if((itemQty(items.at(i)) >99) && (itemId(items.at(i))!=0x1FF)){slot[s].items[i]= itemEncode(itemId(items.at(i)),99);}
793  else{slot[s].items[i]= items.at(i);}
794  }
795  }
796  else{for(int i=0;i<320;i++){slot[s].items[i]= items.at(i);}}
797  setFileModified(true,s);
798 }
799 
800 quint16 FF7Save::itemId(quint16 rawitem){return quint16((itemDecode(rawitem)) & 0x1FF);}
801 quint16 FF7Save::itemId(int s,int item_num){return quint16((itemDecode(slot[s].items[item_num])) & 0x1FF);}
802 quint8 FF7Save::itemQty(int s,int item_num){return quint8(((itemDecode(slot[s].items[item_num]))& 0xFE00) >>9);}
803 quint8 FF7Save::itemQty(quint16 rawitem){return quint8(((itemDecode(rawitem))& 0xFE00) >>9);}
804 
806 {
807  quint8 mask=0;
808  quint8 newheader[0x09] = {0x71,0x73,0x27,0x06,0x00,0x00,0x00,0x00,0x00};
809  //calc 0x04 of the header (selected slot) no idea why they choose this way to do it but slot15 = 0xC2 , slot 14= 0xb2 and so on till slot2 = 0x01 and slot 01 0x00
810  switch(s)
811  {
812  case 0: newheader[4]=0x00; break;
813  case 1: newheader[4]=0x01; break;
814  default:newheader[4]= (16 * (s-2))+2; break;
815  };
816  //calc 0x05 of the header (slots 1-8 empty?)
817  for(int i=0;i<8;i++)
818  {
819  if(isFF7(i)){mask |= (1<<i);}
820  }
821  newheader[5]=mask;
822  mask=0;// reset for the next byte
823  //calc 0x06 of the header (slot 9-15 empty?)
824  for(int i=8;i<15;i++)
825  {
826  if(isFF7(i)){mask |= (1<<(i-8));}
827  }
828  newheader[6]=mask;
829  memcpy(file_headerp,newheader,9);
830 }
831 
833 {if(isFF7(s)){
834  //Time Has to be fixed in the header part of description string.
835  if((slot[s].time/3600)>99){hf[s].sl_header[27]=0x58;hf[s].sl_header[29]=0x58;}
836  else
837  {
838  hf[s].sl_header[27] = ((slot[s].time/3600)/10)+0x4F;
839  hf[s].sl_header[29] = ((slot[s].time/3600)%10)+0x4F;
840  }
841  hf[s].sl_header[33] = ((slot[s].time/60%60)/10)+0x4F;
842  hf[s].sl_header[35] = ((slot[s].time/60%60)%10)+0x4F;
843 }}
844 
846 {
847  fix_psx_header(s);//adjust time.
848  #if (OPENSSL == 1)
849  /* do signing stuff */
850  //qDebug() << QString("key: %1 (%2 bytes)").arg(ps3Key().toHex().toUpper(),QString::number(ps3Key().length()));
851  //qDebug() << QString("Ps3Seed: %1 (%2 bytes)").arg(ps3Seed().toHex().toUpper(),QString::number(ps3Seed().length()));
852 
853  QByteArray keySeed = fileHeader().mid(0x08,20);
854  //qDebug() << QString("Encrypted KeySeed: %1 (%2 bytes)").arg(keySeed.toHex().toUpper(),QString::number(keySeed.length()));
855 
856  QByteArray hmacDigest = fileHeader().mid(0x1C,20);
857  QByteArray signedData = fileHeader().mid(0x30);
858  signedData.append(slotPsxRawData(0));
859  QByteArray decryptedKeySeed;decryptedKeySeed.resize(keySeed.size()+16);
860 
861  const EVP_CIPHER *cipher = EVP_aes_128_cbc();
862  int inLen=keySeed.length();
863  int outLen=0x10;
864 
865  EVP_CIPHER_CTX ctx;
866  EVP_CIPHER_CTX_init(&ctx);
867  EVP_DecryptInit(&ctx, cipher, (const unsigned char*)ps3Key().data(), (const unsigned char*)ps3Seed().data()); //Working on unix
868  EVP_DecryptUpdate(&ctx, (unsigned char*)decryptedKeySeed.data(), &outLen, (const unsigned char*)keySeed.data(), inLen);
869  int tempLen=outLen;
870  EVP_DecryptFinal(&ctx,(unsigned char*)decryptedKeySeed.data()+tempLen,&outLen);
871  EVP_CIPHER_CTX_cleanup(&ctx);
872 
873  decryptedKeySeed.resize(tempLen);
874 
875  //qDebug() << QString("Decrypted KeySeed: %1 (%2 bytes)").arg(decryptedKeySeed.toHex().toUpper(),QString::number(decryptedKeySeed.length()));
876 
877  QByteArray newHMAC; newHMAC.resize(0x14);
878  unsigned int result_len = 0x14;
879  //qDebug() << QString("Signed Data Size:%1 bytes").arg(QString::number(signedData.length()));
880 
881  HMAC_CTX ctx2;
882  HMAC_CTX_init(&ctx2);
883  HMAC_Init(&ctx2, decryptedKeySeed.data(), decryptedKeySeed.length(), EVP_sha1());
884  HMAC_Update(&ctx2, (unsigned char *)signedData.data(), signedData.length());
885  HMAC_Final(&ctx2, ( unsigned char*)newHMAC.data(), &result_len);
886  HMAC_CTX_cleanup(&ctx2);
887  //qDebug() << QString("Files HMAC Digest: %1 (%2 bytes)").arg(hmacDigest.toHex().toUpper(),QString::number(hmacDigest.length()));
888  //qDebug() << QString("New HMAC Digest: %1 (%2 bytes)").arg(newHMAC.toHex().toUpper(), QString::number(newHMAC.length()));
889 
890  QByteArray temp = fileHeader().replace(0x1C,0x14,newHMAC);
891  setFileHeader(temp);
892  #endif
893 }
894 
896 {//Set The Index Section Up.
897  //get list of whats on the card.
898  QByteArray mc_header_2;
899  int index=2;
900  if(SG_TYPE =="PSP"){for(int i=0; i<0x80; i++){mc_header_2.append(file_header_psp[i]);} index=0x82;}
901  if(SG_TYPE =="VGS"){for(int i=0; i<0x40; i++){mc_header_2.append(file_header_vgs[i]);} index=0x42;}
902  if(SG_TYPE =="DEX"){for(int i=0; i<0xF40; i++){mc_header_2.append(file_header_dex[i]);} index=0xF42;}
903  quint8 xor_byte = 0x00;
904  mc_header_2.append("MC");
905  if(SG_TYPE =="MC"){for(int k=0; k<125;k++){mc_header_2.append(file_header_mc[k+index]);}}
906  if(SG_TYPE =="PSP"){for(int k=0; k<125;k++){mc_header_2.append(file_header_psp[k+index]);}}
907  if(SG_TYPE =="VGS"){for(int k=0; k<125;k++){mc_header_2.append(file_header_vgs[k+index]);}}
908  if(SG_TYPE =="DEX"){for(int k=0; k<125;k++){mc_header_2.append(file_header_dex[k+index]);}}
909  xor_byte= 0x00;
910  if(SG_TYPE =="MC"){for(int x=0;x<127;x++){xor_byte^=mc_header_2[x];}}
911  if(SG_TYPE =="PSP"){for(int x=128;x<256;x++){xor_byte^=mc_header_2[x];}}
912  if(SG_TYPE =="VGS"){for(int x=64;x<192;x++){xor_byte^=mc_header_2[x];}}
913  if(SG_TYPE =="DEX"){for(int x=0xF40;x<0x1000;x++){xor_byte^=mc_header_2[x];}}
914  //write xor byte..
915  mc_header_2.append(xor_byte);
916  // thats a normal header
917  for(int i=0;i<15;i++)
918  {
919  //calc xor byte..
920  index= (128 +(128*i));
921  if(SG_TYPE =="PSP"){index+=0x80;}
922  if(SG_TYPE =="VGS"){index+=0x40;}
923  if(SG_TYPE =="DEX"){index+=0xF40;}
924  if(isFF7(i))
925  {
926  QByteArray temp;
927  temp.resize(10);
928  temp[0]=0x51;temp[1]=0x00;temp[2]=0x00;temp[3]=0x00;temp[4]=0x00;
929  temp[5]=0x20;temp[6]=0x00;temp[7]=0x00;temp[8]=0xFF;temp[9]=0xFF;
930  mc_header_2.append(temp);
931  mc_header_2.append(region(i));
932  temp.resize(98);
933  for(int f=0;f<98;f++){temp[f]=0x00;}
934  mc_header_2.append(temp);
935  xor_byte = 0x00;
936  for(int x=0;x<127;x++){xor_byte^=mc_header_2[x+index];}
937  mc_header_2.append(xor_byte);
938 
939  if(region(i).endsWith("FF7-S01"))
940  {for(int P=0;P<512;P++)
941  {
942  if(P<256){hf[i].sl_header[P]= PSX_SAVE_GAME_FILE_HEADER_S01[P];}
943  else{hf[i].sl_header[P]= 0x00;}
944  }
945  }
946  if(region(i).endsWith("FF7-S02"))
947  {for(int P=0;P<512;P++)
948  {
949  if(P<256){hf[i].sl_header[P]= PSX_SAVE_GAME_FILE_HEADER_S02[P];}
950  else{hf[i].sl_header[P]= 0x00;}
951  }
952  }
953  if(region(i).endsWith("FF7-S03"))
954  {for(int P=0;P<512;P++)
955  {
956  if(P<256){hf[i].sl_header[P]= PSX_SAVE_GAME_FILE_HEADER_S03[P];}
957  else{hf[i].sl_header[P]= 0x00;}
958  }
959  }
960  if(region(i).endsWith("FF7-S04"))
961  {for(int P=0;P<512;P++)
962  {
963  if(P<256){hf[i].sl_header[P]= PSX_SAVE_GAME_FILE_HEADER_S04[P];}
964  else{hf[i].sl_header[P]= 0x00;}
965  }
966  }
967  if(region(i).endsWith("FF7-S05"))
968  {for(int P=0;P<512;P++)
969  {
970  if(P<256){hf[i].sl_header[P]= PSX_SAVE_GAME_FILE_HEADER_S05[P];}
971  else{hf[i].sl_header[P]= 0x00;}
972  }
973  }
974  if(region(i).endsWith("FF7-S06"))
975  {for(int P=0;P<512;P++)
976  {
977  if(P<256){hf[i].sl_header[P]= PSX_SAVE_GAME_FILE_HEADER_S06[P];}
978  else{hf[i].sl_header[P]= 0x00;}
979  }
980  }
981  if(region(i).endsWith("FF7-S07"))
982  {for(int P=0;P<512;P++)
983  {
984  if(P<256){hf[i].sl_header[P]= PSX_SAVE_GAME_FILE_HEADER_S07[P];}
985  else{hf[i].sl_header[P]= 0x00;}
986  }
987  }
988  if(region(i).endsWith("FF7-S08"))
989  {for(int P=0;P<512;P++)
990  {
991  if(P<256){hf[i].sl_header[P]= PSX_SAVE_GAME_FILE_HEADER_S08[P];}
992  else{hf[i].sl_header[P]= 0x00;}
993  }
994  }
995  if(region(i).endsWith("FF7-S09"))
996  {for(int P=0;P<512;P++)
997  {
998  if(P<256){hf[i].sl_header[P]= PSX_SAVE_GAME_FILE_HEADER_S09[P];}
999  else{hf[i].sl_header[P]= 0x00;}
1000  }
1001  }
1002  if(region(i).endsWith("FF7-S10"))
1003  {for(int P=0;P<512;P++)
1004  {
1005  if(P<256){hf[i].sl_header[P]= PSX_SAVE_GAME_FILE_HEADER_S10[P];}
1006  else{hf[i].sl_header[P]= 0x00;}
1007  }
1008  }
1009  if(region(i).endsWith("FF7-S11"))
1010  {for(int P=0;P<512;P++)
1011  {
1012  if(P<256){hf[i].sl_header[P]= PSX_SAVE_GAME_FILE_HEADER_S11[P];}
1013  else{hf[i].sl_header[P]= 0x00;}
1014  }
1015  }
1016  if(region(i).endsWith("FF7-S12"))
1017  {for(int P=0;P<512;P++)
1018  {
1019  if(P<256){hf[i].sl_header[P]= PSX_SAVE_GAME_FILE_HEADER_S12[P];}
1020  else{hf[i].sl_header[P]= 0x00;}
1021  }
1022  }
1023  if(region(i).endsWith("FF7-S13"))
1024  {for(int P=0;P<512;P++)
1025  {
1026  if(P<256){hf[i].sl_header[P]= PSX_SAVE_GAME_FILE_HEADER_S13[P];}
1027  else{hf[i].sl_header[P]= 0x00;}
1028  }
1029  }
1030  if(region(i).endsWith("FF7-S14"))
1031  {for(int P=0;P<512;P++)
1032  {
1033  if(P<256){hf[i].sl_header[P]= PSX_SAVE_GAME_FILE_HEADER_S14[P];}
1034  else{hf[i].sl_header[P]= 0x00;}
1035  }
1036  }
1037  if(region(i).endsWith("FF7-S15"))
1038  {for(int P=0;P<512;P++)
1039  {
1040  if(P<256){hf[i].sl_header[P]= PSX_SAVE_GAME_FILE_HEADER_S15[P];}
1041  else{hf[i].sl_header[P]= 0x00;}
1042  }
1043  }
1044  fix_psx_header(i);//fix header in current psx slot
1045  } // write string if found
1046  else
1047  {
1048  if(psx_block_type(i)==0x52 || psx_block_type(i)==0x53)
1049  {
1050  if(SG_TYPE =="MC"){for(int j=0;j<128;j++){mc_header_2.append(file_header_mc[index+j]);}}
1051  if(SG_TYPE =="PSP"){for(int j=0;j<128;j++){mc_header_2.append(file_header_psp[index+j]);}}
1052  if(SG_TYPE =="VGS"){for(int j=0;j<128;j++){mc_header_2.append(file_header_vgs[index+j]);}}
1053  if(SG_TYPE =="DEX"){for(int j=0;j<128;j++){mc_header_2.append(file_header_dex[index+j]);}}
1054  }
1055  else if((region(i).isEmpty() || region(i).isNull()))
1056  {
1057  //QString empty_header = ;
1058  mc_header_2.append("\xA0\x00\x00\x00\x00\x00\x00\x00\xFF\xFF",10);
1059  for (int j=0;j<117;j++){mc_header_2.append('\x00');}
1060  mc_header_2.append('\xA0');
1061  }
1062  else
1063  {//Write What Ever is in the Header (Non ff7 data)
1064  if(SG_TYPE =="MC"){for(int j=0;j<128;j++){mc_header_2.append(file_header_mc[index+j]);}}
1065  if(SG_TYPE =="PSP"){for(int j=0;j<128;j++){mc_header_2.append(file_header_psp[index+j]);}}
1066  if(SG_TYPE =="VGS"){for(int j=0;j<128;j++){mc_header_2.append(file_header_vgs[index+j]);}}
1067  if(SG_TYPE =="DEX"){for(int j=0;j<128;j++){mc_header_2.append(file_header_dex[index+j]);}}
1068  }
1069  }
1070  }
1071 
1072  if(SG_TYPE =="MC")
1073  {
1074  index=2048;
1075  for(int i=0;i<6143;i++){mc_header_2.append(file_header_mc[index+i]);}// fill the remainder
1076  memcpy(file_header_mc,mc_header_2,0x2000);
1077  }
1078  if(SG_TYPE =="PSP")
1079  {
1080  index=2048+0x80;
1081  for(int i=0;i<6143;i++){mc_header_2.append(file_header_psp[index+i]);}// fill the remainder
1082  memcpy(file_header_psp,mc_header_2,0x2080);
1083  //PUT PSP CHECKSUMING HERE ..
1084  }
1085  if(SG_TYPE =="VGS")
1086  {
1087  index=2048+0x40;
1088  for(int i=0;i<6143;i++){mc_header_2.append(file_header_vgs[index+i]);}// fill the remainder
1089  memcpy(file_header_vgs,mc_header_2,0x2040);
1090  }
1091  if(SG_TYPE =="DEX")
1092  {
1093  index=2048+0xF40;
1094  for(int i=0;i<6143;i++){mc_header_2.append(file_header_dex[index+i]);}// fill the remainder
1095  memcpy(file_header_dex,mc_header_2,0x2F40);
1096  }
1097 }
1098 
1099 void FF7Save::setSaveNumber(int s, int saveNum)
1100 {
1101  if(((SG_TYPE =="MC") || (SG_TYPE =="PSP") || (SG_TYPE =="VGS") || (SG_TYPE =="DEX")) && isFF7(s))
1102  {
1103  SG_Region_String[s].chop(2);
1104  SG_Region_String[s].append(QString("%1").arg(QString::number(saveNum),2,QChar('0')));
1105  fix_vmc_header();
1106  }
1107 }
1108 
1109 QString FF7Save::region(int s){return SG_Region_String[s];}
1110 void FF7Save::setRegion(int s ,QString new_region)
1111 {
1112  if( (new_region =="USA") || (new_region == "NTSC-U") || (new_region =="1") )
1113  {
1114  SG_Region_String[s]= QString("BASCUS-94163FF7-S%1").arg(QString::number(s+1),2,QChar('0'));
1115  }
1116  else if( (new_region =="UK") || (new_region =="PAL-E") || (new_region =="2") )
1117  {
1118  SG_Region_String[s]= QString("BESCES-00867FF7-S%1").arg(QString::number(s+1),2,QChar('0'));
1119  }
1120  else if( (new_region =="French") || (new_region =="PAL-FR") || (new_region =="3") )
1121  {
1122  SG_Region_String[s]= QString("BESCES-00868FF7-S%1").arg(QString::number(s+1),2,QChar('0'));
1123  }
1124  else if( (new_region =="German") || (new_region =="PAL-DE") || (new_region =="4") )
1125  {
1126  SG_Region_String[s]= QString("BESCES-00869FF7-S%1").arg(QString::number(s+1),2,QChar('0'));
1127  }
1128  else if( (new_region =="Spanish")||(new_region =="PAL-ES")||(new_region == "5") )
1129  {
1130  SG_Region_String[s]= QString("BESCES-00900FF7-S%1").arg(QString::number(s+1),2,QChar('0'));
1131  }
1132  else if( (new_region =="Japanese")||(new_region =="NTSC-J")||(new_region =="6") )
1133  {
1134  SG_Region_String[s]= QString("BISLPS-00700FF7-S%1").arg(QString::number(s+1),2,QChar('0'));
1135  }
1136  else if( (new_region =="International")||(new_region =="NTSC-JI")||(new_region =="7") )
1137  {
1138  SG_Region_String[s]= QString("BISLPS-01057FF7-S%1").arg(QString::number(s+1),2,QChar('0'));
1139  }
1140  else{SG_Region_String[s]=new_region;}
1141 
1142  if((SG_TYPE =="MC") || (SG_TYPE =="PSP") || (SG_TYPE =="VGS") || (SG_TYPE =="DEX"))
1143  {
1144  if(isFF7(s)){vmcRegionEval(s);}
1145  fix_vmc_header();
1146  }
1147  setFileModified(true,s);
1148 }
1151 {
1152  slot[s]=buffer_slot;
1154  SG_Region_String[s].replace(SG_Region_String[s].length()-2,2,QString("%1").arg(QString::number(s+1),2,QChar('0')));
1155  if( (SG_TYPE =="MC") || (SG_TYPE =="PSP") || (SG_TYPE =="VGS") || (SG_TYPE =="DEX") ){vmcRegionEval(s); fix_vmc_header();}
1156  setFileModified(true,s);
1157 }
1158 
1160 {
1161  if(type()!="PC" && type()!="PSX" && type()!="PSV")
1162  {
1163  int index=128+(128*s);
1164  if (type() =="PSP"){index+=0x80;}
1165  else if (type() =="VGS"){index+=0x40;}
1166  else if (type() =="DEX"){index+=0xF40;}
1167  else {}
1168  return file_headerp[index];
1169  }
1170  else{return 0x00;}
1171 }
1173 {
1174  if(type()!="PC" && type()!="PSX" && type()!="PSV")
1175  {
1176  int index=128+(128*s);
1177  if (type() =="PSP"){index+=0x80;}
1178  else if (type() =="VGS"){index+=0x40;}
1179  else if (type() =="DEX"){index+=0xF40;}
1180  else {}
1181  file_headerp[index]= block_type;
1182  }
1183  else{return;}
1184 }
1185 void FF7Save::setPsx_block_next(int s,int next)
1186 {
1187  if(type()=="PC" || type()=="PSX" || type()=="PSV"){return;}
1188  if(next <0 || next >14){return;}
1189  if(s <0 || s >14){return;}
1190  if(next==s){return;}
1191 
1192  int index=128+(128*s);
1193  if (type() =="PSP"){index+=0x80;}
1194  else if (type() =="VGS"){index+=0x40;}
1195  else if (type() =="DEX"){index+=0xF40;}
1196  else {}
1197  file_headerp[index+0x08]= next;
1198 }
1199 
1201 {
1202  if(type()!="PC" && type() != "PSX" && type() !="PSV")
1203  {
1204  int index=128+(128*s);
1205  if (type() =="PSP"){index+=0x80;}
1206  else if (type() =="VGS"){index+=0x40;}
1207  else if (type() =="DEX"){index+=0xF40;}
1208  else {}
1209  return file_headerp[index+0x08];
1210  }
1211  else{return 0x00;}
1212 }
1213 
1214 void FF7Save::setPsx_block_size(int s,int blockSize)
1215 {
1216  if(type()=="PC" || type()=="PSX" || type()=="PSV"){return;}
1217  if(s <0 || s >14){return;}
1218  if(blockSize>15){return;}
1219 
1220  int index=128+(128*s);
1221  if (type() =="PSP"){index+=0x80;}
1222  else if (type() =="VGS"){index+=0x40;}
1223  else if (type() =="DEX"){index+=0xF40;}
1224 
1225  qint32 filesize= blockSize *0x2000;
1226  file_headerp[index+0x04] = (filesize & 0xff);
1227  file_headerp[index+0x05] = (filesize & 0xff00) >> 8;
1228  file_headerp[index+0x06] = (filesize & 0xff0000) >> 16;
1229 }
1231 {
1232  if(type() =="PC"){return 0;}
1233  else if(type()=="PSV")
1234  {
1235  qint64 size = QFile(fileName()).size();
1236  size -= 0x84;
1237  quint8 v = size / 0x2000;
1238  return v;
1239  }
1240  else if(type()=="PSX")
1241  {
1242  return QFile(fileName()).size() / FF7_PSX_SAVE_GAME_SIZE;
1243  }
1244  else
1245  {
1246  int index=128+(128*s);
1247  if (type() =="PSP"){index+=0x80;}
1248  else if (type() =="VGS"){index+=0x40;}
1249  else if (type() =="DEX"){index+=0xF40;}
1250  else {}
1251  qint32 value = file_headerp[index+0x04] | (file_headerp[index+0x05] << 8) | (file_headerp[index+0x06] <<16);
1252  return value/0x2000;
1253  }
1254 }
1255 
1256 QString FF7Save::psxDesc(int s)
1257 {
1258  QByteArray desc;
1259  QTextCodec *codec = QTextCodec::codecForName(QByteArray("Shift-JIS"));
1260  desc = slotHeader(s).mid(4,64);
1261  int index;
1262  if((index = desc.indexOf('\x00')) != -1) {desc.truncate(index);}
1263  if(codec == 0){return "";}//if the codec can't be loaded for some reason.
1264  else{return codec->toUnicode(desc);}
1265 }
1266 void FF7Save::setPsxDesc(QString newDesc, int s)
1267 {
1268  QTextCodec *codec = QTextCodec::codecForName(QByteArray("Shift-JIS"));
1269  if(codec == 0)
1270  {
1271  qDebug() <<"Failed to Load Codec";
1272  return;
1273  }//if the codec can't be loaded for some reason.
1274  QByteArray temp = codec->fromUnicode(newDesc);
1275 
1276  QByteArray codedText;
1277  codedText.fill('\x00',64);
1278  codedText.replace(0,temp.size(),temp);
1279 
1280  QByteArray header = slotHeader(s);
1281  header.replace(4,64,codedText);
1282  if(setSlotHeader(s,header)){setFileModified(true,s);}
1283 }
1284 
1286 bool FF7Save::isSlotModified(int s){return slotChanged[s];}
1288 {
1289  if(ff7Checksum(s)==0x4D1D){return true;}
1290  else{return false;}
1291 }
1292 bool FF7Save::isFF7(int s)
1293 {
1294  if(region(s).contains("00867") || region(s).contains("00869") ||
1295  region(s).contains("00900") || region(s).contains("94163") ||
1296  region(s).contains("00700") || region(s).contains("01057") ||
1297  region(s).contains("00868"))
1298  {return true;}
1299  else{return false;}
1300 }
1301 
1302 bool FF7Save::isPAL(int s)
1303 {
1304  if(region(s).contains("00867") || region(s).contains("00869") ||
1305  region(s).contains("00900") || region(s).contains("00868"))
1306  {return true;}
1307  else{return false;}
1308 }
1309 
1310 bool FF7Save::isNTSC(int s)
1311 {
1312  if(region(s).contains("00700") || region(s).contains("94163") || region(s).contains("01057"))
1313  {return true;}
1314  else{return false;}
1315 }
1316 bool FF7Save::isJPN(int s)
1317 {
1318  if(region(s).contains("00700") || region(s).contains("01057")){return true;}
1319  else{return false;}
1320 }
1321 int FF7Save::lenFile(void){return SG_SIZE;}
1322 int FF7Save::lenFileHeader(void){return SG_HEADER;}//Return File Header length
1323 int FF7Save::lenFileFooter(void){return SG_FOOTER;}//Return File Footer length
1324 int FF7Save::lenCoreSave(void){return SG_DATA_SIZE;}//Return Slot length (data portion)
1325 int FF7Save::lenSlotHeader(void){return SG_SLOT_HEADER;}//Return slot header length
1326 int FF7Save::lenSlotFooter(void){return SG_SLOT_FOOTER;}//Return slot footer length
1327 int FF7Save::lenSlot(void){return SG_SLOT_SIZE;}//Return Slot length
1328 int FF7Save::numberOfSlots(void){return SG_SLOT_NUMBER;}//Return number of slots in the file_footer_dex
1329 QString FF7Save::type(void){return SG_TYPE;}// Returns the file type loaded.
1330 
1331 void FF7Save::setType(QString type)
1332 {//set up all type stuffs...
1333  if(type == "PC")
1334  {
1343  SG_TYPE = "PC";
1344  file_headerp = file_header_pc; //pointer to pc file header
1345  //file_footerp = file_footer_pc; //pointer to pc file footer
1346 
1347  }
1348  else if(type =="PSX")
1349  {
1358  SG_TYPE = "PSX";
1359  //file_headerp = file_header_psx; //pointer to psx file header
1360  //file_footerp = file_footer_psx; //pointer to psx file footer
1361  }
1362  else if(type=="MC")
1363  {
1372  SG_TYPE = "MC";
1373  file_headerp = file_header_mc; //pointer to mc file header
1374  //file_footerp = file_footer_mc; //pointer to mc file footer
1375  }
1376  else if(type=="PSV")
1377  {
1386  SG_TYPE = "PSV";
1387  file_headerp = file_header_psv; //pointer to psv file header
1388  //file_footerp = file_footer_psv; //pointer to psv file footer
1389  }
1390  else if(type=="PSP")
1391  {
1400  SG_TYPE = "PSP";
1401  file_headerp = file_header_psp; //pointer to psp file header
1402  //file_footerp = file_footer_psp; //pointer to psp file footer
1403  }
1404  else if(type=="VGS")
1405  {
1414  SG_TYPE = "VGS";
1415  file_headerp = file_header_vgs; //pointer to vgs file header
1416  //file_footerp = file_footer_vgs; //pointer to vgs file footer
1417  }
1418  else if(type=="DEX")
1419  {
1428  SG_TYPE = "DEX";
1429  file_headerp = file_header_dex; //pointer to dex file header
1430  //file_footerp = file_footer_dex; //pointer to dex file footer
1431  }
1432 }
1433 void FF7Save::newGame(int s,QString fileName)
1434 {
1435  if(fileName.isEmpty() || fileName.isNull())
1436  {
1437  memcpy(&slot[s],&default_save,0x10F4);
1438  }
1439  else
1440  {
1441  QFile file(fileName);
1442  if(!file.open(QFile::ReadOnly)){return;}
1443  QByteArray ff7file;
1444  ff7file = file.readAll(); //put all data in temp raw file
1445  QByteArray temp; // create a temp to be used when needed
1446  int index = 0x200;
1447  temp = ff7file.mid(index,0x10f4);
1448  memcpy(&slot[s],temp,0x10f4);
1449  }
1450  if(isJPN(s))
1451  {
1452  for(int c=0;c<9;c++){setCharName(s,c,"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff");}// clear all names.
1453  Text.init(1);
1454  setCharName(s,0,QString::fromUtf8("元ソルジャー"));
1455  setCharName(s,1,QString::fromUtf8("バレット"));
1456  setCharName(s,2,QString::fromUtf8("ティファ"));
1457  setCharName(s,3,QString::fromUtf8("エアリス"));
1458  setCharName(s,4,QString::fromUtf8("レッド⑬"));
1459  setCharName(s,5,QString::fromUtf8("ユフィ"));
1460  setCharName(s,6,QString::fromUtf8("昔のクラウド"));
1461  setCharName(s,7,QString::fromUtf8("セフィロス"));
1462  setCharName(s,8,QString::fromUtf8("シド"));
1463  setDescName(s,QString::fromUtf8("元ソルジャー"));
1464  setDescLocation(s,QString::fromUtf8("1番街駅ホーム"));
1465  setLocation(s,QString::fromUtf8("1番街駅ホーム"));
1466  }
1467  else if(region(s).isEmpty()){setRegion(s,QString("BASCUS-94163FF7-S%1").arg(QString::number(s+1),2,QChar('0')));Text.init(0);}
1468  setFileModified(true,s);
1469 }
1470 
1471 void FF7Save::newGamePlus(int s,QString CharFileName,QString fileName)
1472 {
1473  if(fileName.isEmpty() || fileName.isNull())
1474  {
1475  memcpy(&buffer_slot,&default_save,0x10F4);
1476  }
1477  else
1478  {
1479  QFile file(fileName);
1480  if(!file.open(QFile::ReadOnly)){return;}
1481  QByteArray ff7file;
1482  ff7file = file.readAll(); //put all data in temp raw file
1483  QByteArray temp; // create a temp to be used when needed
1484  int index = 0x200;
1485  temp = ff7file.mid(index,0x10f4);
1486  memcpy(&buffer_slot,temp,0x10f4);
1487  }
1488  buffer_region = region(s);
1489  memcpy(&buffer_slot.desc,&slot[s].desc,0x44); // keep a old preview
1490  memcpy(&buffer_slot.colors,&slot[s].colors,12); // keep old colors.
1491 
1492  for(int i=0;i<9;i++) // keep all old character info.
1493  {
1494  if((i==6)||(i==7))// except we have to export cait sith and vincent.the game needs y.cloud/seppie,for the flash back.
1495  {
1496  QString outFile;
1497  if(i==6) //export cait sith. cait sith's stats are only generated when he joins the party.
1498  {
1499  outFile.append(CharFileName);
1500  outFile.append("-cait_sith");
1501  if(type() != "PSX" || type() != "PSV")
1502  {
1503  outFile.append("-");
1504  QString str;
1505  str.setNum(s,10)+1;
1506  outFile.append(str);
1507  }
1508  }
1509  else if(i==7)// export vincent. vincent's stats are only generated when he joins the party.
1510  {
1511  outFile.append(CharFileName);
1512  outFile.append("-vincent");
1513  if(type() != "PSX" || type() != "PSV")
1514  {
1515  outFile.append("-");
1516  QString str;
1517  str.setNum(s,10)+1;
1518  outFile.append(str);
1519  }
1520  }
1521  outFile.append(".char");
1522  exportCharacter(s,i,outFile);
1523 
1524  }
1525  else{memcpy(&buffer_slot.chars[i],&slot[s].chars[i],0x84);} // normal character
1526  }
1527  memcpy(&buffer_slot.items,&slot[s].items,640);// copy items
1528  memcpy(&buffer_slot.materias,&slot[s].materias,800); // copy materia
1529  buffer_slot.gil = slot[s].gil; // copy gil
1530  buffer_slot.battles = slot[s].battles; // copy battle count
1531  buffer_slot.runs = slot[s].runs; // copy run count
1532  buffer_slot.gp = slot[s].gp; // copy gp
1533  //copy chocobo info.
1534  buffer_slot.stables = slot[s].stables;
1535  buffer_slot.stablesoccupied = slot[s].stablesoccupied;
1536  buffer_slot.chocobomask = slot[s].chocobomask;
1537  for(int i=0;i<4;i++){buffer_slot.chocobos[i]=slot[s].chocobos[i];}
1538  memcpy(&buffer_slot.chocobonames,slot[s].chocobonames,36);
1539  memcpy(&buffer_slot.chocostaminas,slot[s].chocostaminas,12);
1540  for(int i=0;i<2;i++){buffer_slot.choco56[i]=slot[s].choco56[i];}
1541  // copy options
1542  buffer_slot.battlespeed =slot[s].battlespeed;
1543  buffer_slot.battlemspeed =slot[s].battlemspeed;
1544  buffer_slot.options=slot[s].options;
1545  memcpy(&buffer_slot.controller_map,slot[s].controller_map,16);
1546  buffer_slot.fieldmspeed = slot[s].fieldmspeed;
1547  //~~ buffer now ready to be copied~
1548  slot[s]=buffer_slot;
1549  setLocation(s,QT_TRANSLATE_NOOP("FF7Save","New Game +"));
1550  setFileModified(true,s);
1551 }
1552 quint8 FF7Save::disc(int s){return slot[s].disc;}
1553 void FF7Save::setDisc(int s, int disc)
1554 {
1555  if(disc<1 || disc>3){return;}
1556  else{slot[s].disc=disc;setFileModified(true,s);}
1557 }
1559 {
1560  if(s<0 || s>14){return 0;}
1561  else{return slot[s].mprogress;}
1562 }
1563 void FF7Save::setMainProgress(int s,int mProgress)
1564 {
1565  if(s<0 || s>14){return;}
1566  else
1567  {
1568  if(mProgress<0){mProgress =0;}
1569  else if(mProgress>0xFFFF){mProgress=0xFFFF;}
1570  if(mProgress != slot[s].mprogress)
1571  {
1572  slot[s].mprogress = mProgress;
1573  setFileModified(true,s);
1574  }
1575  }
1576 }
1577 
1578 QList<QByteArray> FF7Save::slotIcon(int s)
1579 {
1580  QList<QByteArray> icon;
1581 
1582  if(slotHeader(s).at(2) >= 0x11)
1583  {
1584  icon.append(slotHeader(s).mid(96,160));
1585  if(slotHeader(s).at(2) >= 0x12)
1586  {
1587  icon.append(slotHeader(s).mid(256,128));
1588  if(slotHeader(s).at(2) == 0x13)
1589  {
1590  icon.append(slotHeader(s).mid(384,128));
1591  }
1592  }
1593  }
1594  else
1595  {
1596  QByteArray tmp;
1597  tmp.fill(00,0x200);
1598  icon.append(tmp);
1599  }
1600  return icon;
1601 }
1602 QString FF7Save::charName(int s,int char_num)
1603 {
1604  if(isJPN(s)){Text.init(1);}//Japanese
1605  else{Text.init(0);}// not japanese save.
1606  QByteArray text;
1607  for (int n=0;n<12;n++){text.append(slot[s].chars[char_num].name[n]);}
1608  return Text.toPC(text);
1609 }
1610 void FF7Save::setCharName(int s,int char_num,QString new_name)
1611 {
1612  if(isJPN(s)){Text.init(1);}//Japanese
1613  else{Text.init(0);}// not japanese save.
1614  for (int i=0;i<12;i++){slot[s].chars[char_num].name[i] =0xFF;}
1615  QByteArray temp = Text.toFF7(new_name);
1616  memcpy(slot[s].chars[char_num].name,temp,temp.length());
1617  setFileModified(true,s);
1618 }
1619 
1620 QString FF7Save::descName(int s)
1621 {
1622  if(isJPN(s)){Text.init(1);}//Japanese
1623  else{Text.init(0);}// not japanese save.
1624  QByteArray text;
1625  for (int n=0;n<16;n++){text.append(slot[s].desc.name[n]);}
1626  return Text.toPC(text);
1627 }
1628 void FF7Save::setDescName(int s,QString new_name)
1629 {
1630  if(isJPN(s)){Text.init(1);}//Japanese
1631  else{Text.init(0);}// not japanese save.
1632  for (int i=0;i<16;i++){slot[s].desc.name[i] =0xFF;}
1633  QByteArray temp = Text.toFF7(new_name);
1634  memcpy(slot[s].desc.name,temp,temp.length());
1635  setFileModified(true,s);
1636 }
1637 
1639 {
1640  if(isJPN(s)){Text.init(1);}//Japanese
1641  else{Text.init(0);}// not japanese save.
1642  QByteArray text;
1643  for (int n=0;n<24;n++){text.append(slot[s].desc.location[n]);}
1644  return Text.toPC(text);
1645 }
1646 
1647 void FF7Save::setDescLocation(int s, QString new_desc_location)
1648 {
1649  if(isJPN(s)){Text.init(1);}//Japanese
1650  else{Text.init(0);}// not japanese save.
1651  QByteArray text;
1652  for (int i=0;i<32;i++){slot[s].desc.location[i] =0xFF;}
1653  QByteArray temp = Text.toFF7(new_desc_location);
1654  memcpy(slot[s].desc.location,temp,temp.length());
1655  setFileModified(true,s);
1656 }
1657 
1658 quint8 FF7Save::descLevel(int s){return slot[s].desc.level;}
1659 quint8 FF7Save::descParty(int s,int char_num)
1660 {
1661  return slot[s].desc.party[char_num];
1662 }
1663 quint16 FF7Save::descCurHP(int s){return slot[s].desc.curHP;}
1664 quint16 FF7Save::descMaxHP(int s){return slot[s].desc.maxHP;}
1665 quint16 FF7Save::descCurMP(int s){return slot[s].desc.curMP;}
1666 quint16 FF7Save::descMaxMP(int s){return slot[s].desc.maxMP;}
1667 quint32 FF7Save::descGil(int s){return slot[s].desc.gil;}
1668 void FF7Save::setDescLevel(int s,int new_level){slot[s].desc.level=new_level;setFileModified(true,s);}
1669 
1670 void FF7Save::setDescParty(int s,int char_num,quint8 new_id){slot[s].desc.party[char_num]=new_id;setFileModified(true,s);}
1671 void FF7Save::setDescCurHP(int s,quint16 new_curHP){slot[s].desc.curHP=new_curHP;setFileModified(true,s);}
1672 void FF7Save::setDescMaxHP(int s,quint16 new_maxHP){slot[s].desc.maxHP=new_maxHP;setFileModified(true,s);}
1673 void FF7Save::setDescCurMP(int s,quint16 new_curMP){slot[s].desc.curMP=new_curMP;setFileModified(true,s);}
1674 void FF7Save::setDescMaxMP(int s,quint16 new_maxMP){slot[s].desc.maxMP=new_maxMP;setFileModified(true,s);}
1675 void FF7Save::setDescGil(int s,quint32 new_gil){slot[s].desc.gil=new_gil;setFileModified(true,s);}
1676 
1677 quint32 FF7Save::descTime(int s){return slot[s].desc.time;}
1678 void FF7Save::setDescTime(int s,quint32 new_time){slot[s].desc.time=new_time;setFileModified(true,s);}
1679 
1680 quint32 FF7Save::time(int s) {return slot[s].time;}
1681 
1682 void FF7Save::setTime(int s,quint32 new_time)
1683 {
1684  slot[s].time=new_time;
1685  setDescTime(s,new_time);//set Desc also.
1686  setFileModified(true,s);
1687 }
1688 
1689 QString FF7Save::location(int s)
1690 {
1691 
1692  if(isJPN(s)){Text.init(1);}//Japanese
1693  else{Text.init(0);}// not japanese save.
1694  QByteArray text;
1695  for (int n=0;n<24;n++){text.append(slot[s].location[n]);}
1696  return Text.toPC(text);
1697 }
1698 void FF7Save::setLocation(int s, QString new_location)
1699 {
1700  if(isJPN(s)){Text.init(1);}//Japanese
1701  else{Text.init(0);}// not japanese save.
1702  QByteArray text;
1703  for (int i=0;i<24;i++){slot[s].location[i] =0xFF;}
1704  QByteArray temp = Text.toFF7(new_location);
1705  memcpy(slot[s].location,temp,temp.length());
1706  //and the description.
1707  setDescLocation(s,new_location);
1708  setFileModified(true,s);
1709 }
1710 quint8 FF7Save::love(int s,bool battle, FF7Save::LOVER who)
1711 {
1712  if(battle)
1713  {
1714  switch(who)
1715  {
1716  case FF7Save::LOVE_BARRET: return slot[s].b_love.barret; break;
1717  case FF7Save::LOVE_TIFA: return slot[s].b_love.tifa; break;
1718  case FF7Save::LOVE_AERIS: return slot[s].b_love.aeris; break;
1719  case FF7Save::LOVE_YUFFIE: return slot[s].b_love.yuffie; break;
1720  default: return 0; break;
1721  }
1722  }
1723  else
1724  {
1725  switch(who)
1726  {
1727  case FF7Save::LOVE_BARRET: return slot[s].love.barret; break;
1728  case FF7Save::LOVE_TIFA: return slot[s].love.tifa; break;
1729  case FF7Save::LOVE_AERIS: return slot[s].love.aeris; break;
1730  case FF7Save::LOVE_YUFFIE: return slot[s].love.yuffie; break;
1731  default: return 0; break;
1732  }
1733  }
1734 }
1735 void FF7Save::setLove(int s,bool battle, FF7Save::LOVER who ,quint8 love)
1736 {
1737  if(battle)
1738  {
1739  switch(who)
1740  {
1741  case FF7Save::LOVE_BARRET: slot[s].b_love.barret = love;setFileModified(true,s); break;
1742  case FF7Save::LOVE_TIFA: slot[s].b_love.tifa=love;setFileModified(true,s); break;
1743  case FF7Save::LOVE_AERIS: slot[s].b_love.aeris=love;setFileModified(true,s); break;
1744  case FF7Save::LOVE_YUFFIE: slot[s].b_love.yuffie=love;setFileModified(true,s); break;
1745  default: break;
1746  }
1747  }
1748  else
1749  {
1750  switch(who)
1751  {
1752  case FF7Save::LOVE_BARRET: slot[s].love.barret = love;setFileModified(true,s); break;
1753  case FF7Save::LOVE_TIFA: slot[s].love.tifa=love;setFileModified(true,s); break;
1754  case FF7Save::LOVE_AERIS: slot[s].love.aeris=love;setFileModified(true,s); break;
1755  case FF7Save::LOVE_YUFFIE: slot[s].love.yuffie=love;setFileModified(true,s); break;
1756  default: break;
1757  }
1758  }
1759 }
1761 {
1762  switch(cave)
1763  {
1764  case FF7Save::CAVE_MIME: return (slot[s].materiacaves &(1<<0)); break;
1765  case FF7Save::CAVE_HPMP: return (slot[s].materiacaves &(1<<1)); break;
1766  case FF7Save::CAVE_QUADMAGIC: return (slot[s].materiacaves & (1<<2)); break;
1767  case FF7Save::CAVE_KOTR: return (slot[s].materiacaves & (1<<3)); break;
1768  default: return false;
1769  }
1770 }
1771 void FF7Save::setMateriaCave(int s, FF7Save::MATERIACAVE cave, bool isEmpty)
1772 {
1773  switch(cave)
1774  {
1775  case FF7Save::CAVE_MIME:
1776  if(isEmpty){slot[s].materiacaves |= (1<<0);}
1777  else{slot[s].materiacaves &= ~(1<<0);}
1778  setFileModified(true,s);
1779  break;
1780 
1781  case FF7Save::CAVE_HPMP:
1782  if(isEmpty){slot[s].materiacaves |= (1<<1);}
1783  else{slot[s].materiacaves &= ~(1<<1);}
1784  setFileModified(true,s);
1785  break;
1786 
1788  if(isEmpty){slot[s].materiacaves |= (1<<2);}
1789  else{slot[s].materiacaves &= ~(1<<2);}
1790  setFileModified(true,s);
1791  break;
1792 
1793  case FF7Save::CAVE_KOTR:
1794  if(isEmpty){slot[s].materiacaves |= (1<<3);}
1795  else{slot[s].materiacaves &= ~(1<<3);}
1796  setFileModified(true,s);
1797  break;
1798 
1799  default: break;
1800  }
1801 }
1802 quint16 FF7Save::speedScore(int s, int rank)
1803 {
1804  switch(rank)
1805  {
1806  case 1: return slot[s].coster_1; break;
1807  case 2: return slot[s].coster_2; break;
1808  case 3: return slot[s].coster_3; break;
1809  default: return 0; break;
1810  }
1811 }
1812 void FF7Save::setSpeedScore(int s, int rank,quint16 score)
1813 {
1814  switch(rank)
1815  {
1816  case 1: slot[s].coster_1=score;setFileModified(true,s); break;
1817  case 2: slot[s].coster_2=score;setFileModified(true,s); break;
1818  case 3: slot[s].coster_3=score;setFileModified(true,s); break;
1819  default: break;
1820  }
1821 }
1822 
1823 QString FF7Save::chocoName(int s,int choco_num)
1824 {
1825  if(isJPN(s)){Text.init(1);}//Japanese
1826  else{Text.init(0);}// not japanese save.
1827  QByteArray text;
1828  for (int n=0;n<6;n++){text.append(slot[s].chocobonames[choco_num][n]);}
1829  return Text.toPC(text);
1830 }
1831 void FF7Save::setChocoName(int s,int choco_num,QString new_name)
1832 {
1833  if(isJPN(s)){Text.init(1);}//Japanese
1834  else{Text.init(0);}// not japanese save.
1835  QByteArray temp = Text.toFF7(new_name);
1836  for (int i=0;i<6;i++){slot[s].chocobonames[choco_num][i] =0xFF;}
1837  memcpy(slot[s].chocobonames[choco_num],temp,temp.length());
1838  setFileModified(true,s);
1839 }
1840 void FF7Save::setPartyMateria(int s, int mat_num, quint8 id,qint32 ap)
1841 {//if invalid set to 0xFF
1842  if( (id<91) && ((ap>=0)&&(ap<=16777215)))
1843  {//Valid Id and Ap provided.
1844  slot[s].materias[mat_num].id = id;
1845  int a = (ap & 0xff);
1846  int b = (ap & 0xff00) >> 8;
1847  int c = (ap & 0xff0000) >> 16;
1848  slot[s].materias[mat_num].ap[0]=a;
1849  slot[s].materias[mat_num].ap[1]=b;
1850  slot[s].materias[mat_num].ap[2]=c;
1851  }
1852  else
1853  {//invalid ID set Empty
1854  slot[s].materias[mat_num].id =0xFF;
1855  slot[s].materias[mat_num].ap[0]=0xFF;
1856  slot[s].materias[mat_num].ap[1]=0xFF;
1857  slot[s].materias[mat_num].ap[2]=0xFF;
1858  }
1859  setFileModified(true,s);
1860 }
1861 quint8 FF7Save::partyMateriaId(int s,int mat_num){return slot[s].materias[mat_num].id;}
1862 qint32 FF7Save::partyMateriaAp(int s,int mat_num)
1863 {
1864  qint32 ap_temp = slot[s].materias[mat_num].ap[0] |(slot[s].materias[mat_num].ap[1] << 8) | slot[s].materias[mat_num].ap[2]<<16;
1865  return ap_temp;
1866 }
1867 void FF7Save::setStolenMateria(int s, int mat_num, quint8 id,qint32 ap)
1868 {
1869  if( (id<91) && ((ap>=0)&&(ap<=16777215)))
1870  {//Valid Id and Ap provided.
1871  slot[s].stolen[mat_num].id = id;
1872  int a = (ap & 0xff);
1873  int b = (ap & 0xff00) >> 8;
1874  int c = (ap & 0xff0000) >> 16;
1875  slot[s].stolen[mat_num].ap[0]=a;
1876  slot[s].stolen[mat_num].ap[1]=b;
1877  slot[s].stolen[mat_num].ap[2]=c;
1878  }
1879  else
1880  {//invalid ID set Empty
1881  slot[s].stolen[mat_num].id =0xFF;
1882  slot[s].stolen[mat_num].ap[0]=0xFF;
1883  slot[s].stolen[mat_num].ap[1]=0xFF;
1884  slot[s].stolen[mat_num].ap[2]=0xFF;
1885  }
1886  setFileModified(true,s);
1887 }
1888 quint8 FF7Save::stolenMateriaId(int s,int mat_num){return slot[s].stolen[mat_num].id;}
1889 
1890 qint32 FF7Save::stolenMateriaAp(int s,int mat_num)
1891 {
1892  qint32 ap_temp = slot[s].stolen[mat_num].ap[0] |(slot[s].stolen[mat_num].ap[1] << 8) | slot[s].stolen[mat_num].ap[2]<<16;
1893  return ap_temp;
1894 }
1895 QColor FF7Save::dialogColorUL(int s){return QColor(slot[s].colors[0][0],slot[s].colors[0][1],slot[s].colors[0][2]);}
1896 QColor FF7Save::dialogColorUR(int s){return QColor(slot[s].colors[1][0],slot[s].colors[1][1],slot[s].colors[1][2]);}
1897 QColor FF7Save::dialogColorLL(int s){return QColor(slot[s].colors[2][0],slot[s].colors[2][1],slot[s].colors[2][2]);}
1898 QColor FF7Save::dialogColorLR(int s){return QColor(slot[s].colors[3][0],slot[s].colors[3][1],slot[s].colors[3][2]);}
1899 
1900 void FF7Save::setDialogColorUL(int s, QColor color)
1901 {
1902  slot[s].colors[0][0]=color.red();
1903  slot[s].colors[0][1]=color.green();
1904  slot[s].colors[0][2]= color.blue();
1905  setFileModified(true,s);
1906 }
1907 void FF7Save::setDialogColorUR(int s, QColor color)
1908 {
1909  slot[s].colors[1][0]=color.red();
1910  slot[s].colors[1][1]=color.green();
1911  slot[s].colors[1][2]= color.blue();
1912  setFileModified(true,s);
1913 }
1914 void FF7Save::setDialogColorLL(int s, QColor color)
1915 {
1916  slot[s].colors[2][0]=color.red();
1917  slot[s].colors[2][1]=color.green();
1918  slot[s].colors[2][2]= color.blue();
1919  setFileModified(true,s);
1920 }
1921 void FF7Save::setDialogColorLR(int s, QColor color)
1922 {
1923  slot[s].colors[3][0]=color.red();
1924  slot[s].colors[3][1]=color.green();
1925  slot[s].colors[3][2]= color.blue();
1926  setFileModified(true,s);
1927 }
1928 void FF7Save::setCharacter(int s,int char_num,FF7CHAR new_char){slot[s].chars[char_num] = new_char;}
1929 
1930 FF7CHAR FF7Save::character(int s,int char_num){return slot[s].chars[char_num];}
1931 
1932 QByteArray FF7Save::rawCharacterData(int s, int char_num)
1933 {
1934  QByteArray temp;
1935  temp.setRawData(reinterpret_cast <char *>(&slot[s].chars[char_num]),132);
1936  return temp;
1937 }
1938 quint8 FF7Save::charID(int s,int char_num){return slot[s].chars[char_num].id;}
1939 quint8 FF7Save::charLevel(int s,int char_num){return slot[s].chars[char_num].level;}
1940 quint8 FF7Save::charStr(int s,int char_num){return slot[s].chars[char_num].strength;}
1941 quint8 FF7Save::charVit(int s,int char_num){return slot[s].chars[char_num].vitality;}
1942 quint8 FF7Save::charMag(int s,int char_num){return slot[s].chars[char_num].magic;}
1943 quint8 FF7Save::charSpi(int s,int char_num){return slot[s].chars[char_num].spirit;}
1944 quint8 FF7Save::charDex(int s,int char_num){return slot[s].chars[char_num].dexterity;}
1945 quint8 FF7Save::charLck(int s,int char_num){return slot[s].chars[char_num].luck;}
1946 quint8 FF7Save::charStrBonus(int s,int char_num){return slot[s].chars[char_num].strength_bonus;}
1947 quint8 FF7Save::charVitBonus(int s,int char_num){return slot[s].chars[char_num].vitality_bonus;}
1948 quint8 FF7Save::charMagBonus(int s,int char_num){return slot[s].chars[char_num].magic_bonus;}
1949 quint8 FF7Save::charSpiBonus(int s,int char_num){return slot[s].chars[char_num].spirit_bonus;}
1950 quint8 FF7Save::charDexBonus(int s,int char_num){return slot[s].chars[char_num].dexterity_bonus;}
1951 quint8 FF7Save::charLckBonus(int s,int char_num){return slot[s].chars[char_num].luck_bonus;}
1952 qint8 FF7Save::charLimitLevel(int s,int char_num){return slot[s].chars[char_num].limitlevel;}
1953 quint8 FF7Save::charLimitBar(int s,int char_num){return slot[s].chars[char_num].limitbar;}
1954 quint8 FF7Save::charWeapon(int s,int char_num){return slot[s].chars[char_num].weapon;}
1955 quint8 FF7Save::charArmor(int s,int char_num){return slot[s].chars[char_num].armor;}
1956 quint8 FF7Save::charAccessory(int s,int char_num){return slot[s].chars[char_num].accessory;}
1957 quint8 FF7Save::charFlag(int s,int char_num,int flag_num){return slot[s].chars[char_num].flags[flag_num];}
1958 quint16 FF7Save::charLimits(int s,int char_num){return slot[s].chars[char_num].limits;}
1959 quint16 FF7Save::charKills(int s,int char_num){return slot[s].chars[char_num].kills;}
1960 
1961 quint16 FF7Save::charTimesLimitUsed(int s,int char_num,int level)
1962 {
1963  switch(level)
1964  {
1965  case 1:return slot[s].chars[char_num].timesused1;break;
1966  case 2:return slot[s].chars[char_num].timesused2;break;
1967  case 3:return slot[s].chars[char_num].timesused3;break;
1968  default:return 0;
1969  }
1970 }
1971 
1972 quint16 FF7Save::charCurrentHp(int s,int char_num){return slot[s].chars[char_num].curHP;}
1973 quint16 FF7Save::charBaseHp(int s,int char_num){return slot[s].chars[char_num].baseHP;}
1974 quint16 FF7Save::charCurrentMp(int s,int char_num){return slot[s].chars[char_num].curMP;}
1975 quint16 FF7Save::charBaseMp(int s,int char_num){return slot[s].chars[char_num].baseMP;}
1976 quint8 FF7Save::charUnknown(int s,int char_num,int unknown_num){return slot[s].chars[char_num].z_4[unknown_num];}
1977 quint16 FF7Save::charMaxHp(int s,int char_num){return slot[s].chars[char_num].maxHP;}
1978 quint16 FF7Save::charMaxMp(int s,int char_num){return slot[s].chars[char_num].maxMP;}
1979 quint32 FF7Save::charCurrentExp(int s,int char_num){return slot[s].chars[char_num].exp;}
1980 quint32 FF7Save::charNextExp(int s,int char_num){return slot[s].chars[char_num].expNext;}
1981 
1982 void FF7Save::setCharID(int s,int char_num,qint8 new_id){slot[s].chars[char_num].id=new_id;setFileModified(true,s);}
1983 void FF7Save::setCharLevel(int s,int char_num,qint8 new_level){slot[s].chars[char_num].level=new_level;setFileModified(true,s);}
1984 void FF7Save::setCharStr(int s,int char_num,quint8 str){slot[s].chars[char_num].strength=str;setFileModified(true,s);}
1985 void FF7Save::setCharVit(int s,int char_num,quint8 vit){slot[s].chars[char_num].vitality=vit;setFileModified(true,s);}
1986 void FF7Save::setCharMag(int s,int char_num,quint8 mag){slot[s].chars[char_num].magic=mag;setFileModified(true,s);}
1987 void FF7Save::setCharSpi(int s,int char_num,quint8 spi){slot[s].chars[char_num].spirit=spi;setFileModified(true,s);}
1988 void FF7Save::setCharDex(int s,int char_num,quint8 dex){slot[s].chars[char_num].dexterity=dex;setFileModified(true,s);}
1989 void FF7Save::setCharLck(int s,int char_num,quint8 lck){slot[s].chars[char_num].luck=lck;setFileModified(true,s);}
1990 void FF7Save::setCharStrBonus(int s,int char_num,quint8 strbonus){slot[s].chars[char_num].strength_bonus=strbonus;setFileModified(true,s);}
1991 void FF7Save::setCharVitBonus(int s,int char_num,quint8 vitbonus){slot[s].chars[char_num].vitality_bonus=vitbonus;setFileModified(true,s);}
1992 void FF7Save::setCharMagBonus(int s,int char_num,quint8 magbonus){slot[s].chars[char_num].magic_bonus=magbonus;setFileModified(true,s);}
1993 void FF7Save::setCharSpiBonus(int s,int char_num,quint8 spibonus){slot[s].chars[char_num].spirit_bonus=spibonus;setFileModified(true,s);}
1994 void FF7Save::setCharDexBonus(int s,int char_num,quint8 dexbonus){slot[s].chars[char_num].dexterity_bonus=dexbonus;setFileModified(true,s);}
1995 void FF7Save::setCharLckBonus(int s,int char_num,quint8 lckbonus){slot[s].chars[char_num].luck_bonus=lckbonus;setFileModified(true,s);}
1996 void FF7Save::setCharLimitLevel(int s,int char_num,qint8 limitlevel){slot[s].chars[char_num].limitlevel=limitlevel;setFileModified(true,s);}
1997 void FF7Save::setCharLimitBar(int s,int char_num,quint8 limitbar){slot[s].chars[char_num].limitbar=limitbar;setFileModified(true,s);}
1998 void FF7Save::setCharWeapon(int s,int char_num,quint8 weapon){slot[s].chars[char_num].weapon=weapon;setFileModified(true,s);}
1999 void FF7Save::setCharArmor(int s,int char_num,quint8 armor){slot[s].chars[char_num].armor=armor;setFileModified(true,s);}
2000 void FF7Save::setCharAccessory(int s,int char_num,quint8 accessory){slot[s].chars[char_num].accessory=accessory;setFileModified(true,s);}
2001 void FF7Save::setCharFlag(int s,int char_num,int flag_num,quint8 flag_value){slot[s].chars[char_num].flags[flag_num]=flag_value;setFileModified(true,s);}
2002 void FF7Save::setCharLimits(int s,int char_num,quint16 new_limits){slot[s].chars[char_num].limits=new_limits;setFileModified(true,s);}
2003 void FF7Save::setCharKills(int s,int char_num,quint16 new_level){slot[s].chars[char_num].kills=new_level;setFileModified(true,s);}
2004 void FF7Save::setCharTimeLimitUsed(int s,int char_num,int level,quint16 timesused)
2005 {
2006  switch(level)
2007  {
2008  case 1:slot[s].chars[char_num].timesused1=timesused;setFileModified(true,s);break;
2009  case 2:slot[s].chars[char_num].timesused2=timesused;setFileModified(true,s);break;
2010  case 3:slot[s].chars[char_num].timesused3=timesused;setFileModified(true,s);break;
2011  }
2012 }
2013 void FF7Save::setCharCurrentHp(int s,int char_num,quint16 curHp){slot[s].chars[char_num].curHP=curHp;setFileModified(true,s);}
2014 void FF7Save::setCharBaseHp(int s,int char_num,quint16 baseHp){slot[s].chars[char_num].baseHP=baseHp;setFileModified(true,s);}
2015 void FF7Save::setCharCurrentMp(int s,int char_num,quint16 curMp){slot[s].chars[char_num].curMP=curMp;setFileModified(true,s);}
2016 void FF7Save::setCharBaseMp(int s,int char_num,quint16 baseMp){slot[s].chars[char_num].baseMP=baseMp;setFileModified(true,s);}
2017 void FF7Save::setCharUnknown(int s,int char_num,int unknown_num,quint8 value){slot[s].chars[char_num].z_4[unknown_num]=value;setFileModified(true,s);}
2018 void FF7Save::setCharMaxHp(int s,int char_num,quint16 maxHp){slot[s].chars[char_num].maxHP=maxHp;setFileModified(true,s);}
2019 void FF7Save::setCharMaxMp(int s,int char_num,quint16 maxMp){slot[s].chars[char_num].maxMP=maxMp;setFileModified(true,s);}
2020 void FF7Save::setCharCurrentExp(int s,int char_num,quint32 exp){slot[s].chars[char_num].exp=exp;setFileModified(true,s);}
2021 void FF7Save::setCharNextExp(int s,int char_num,quint32 next){slot[s].chars[char_num].expNext=next;setFileModified(true,s);}
2022 
2023 void FF7Save::setCharMateria(int s,int who,int mat_num,quint8 id,qint32 ap)
2024 {
2025  if( (id<91) && ((ap>=0)&&(ap<=16777215)))
2026  {//Valid Id and Ap provided.
2027  slot[s].chars[who].materias[mat_num].id = id;
2028  int a = (ap & 0xff);
2029  int b = (ap & 0xff00) >> 8;
2030  int c = (ap & 0xff0000) >> 16;
2031  slot[s].chars[who].materias[mat_num].ap[0]=a;
2032  slot[s].chars[who].materias[mat_num].ap[1]=b;
2033  slot[s].chars[who].materias[mat_num].ap[2]=c;
2034  }
2035  else
2036  {//invalid ID set Empty
2037  slot[s].chars[who].materias[mat_num].id =0xFF;
2038  slot[s].chars[who].materias[mat_num].ap[0]=0xFF;
2039  slot[s].chars[who].materias[mat_num].ap[1]=0xFF;
2040  slot[s].chars[who].materias[mat_num].ap[2]=0xFF;
2041  }
2042  setFileModified(true,s);
2043 }
2044 void FF7Save::setCharMateria(int s, int who, int mat_num, materia mat){slot[s].chars[who].materias[mat_num] = mat;setFileModified(true,s);}
2045 quint8 FF7Save::charMateriaId(int s,int who,int mat_num){return slot[s].chars[who].materias[mat_num].id;}
2046 qint32 FF7Save::charMateriaAp(int s,int who,int mat_num)
2047 {
2048  qint32 ap_temp = slot[s].chars[who].materias[mat_num].ap[0] |(slot[s].chars[who].materias[mat_num].ap[1] << 8) | slot[s].chars[who].materias[mat_num].ap[2]<<16;
2049  return ap_temp;
2050 }
2051 FF7CHOCOBO FF7Save::chocobo(int s, int chocoSlot)
2052 {
2053  if(chocoSlot >-1 && chocoSlot <4){return slot[s].chocobos[chocoSlot];}
2054  else if (chocoSlot ==4){return slot[s].choco56[0];}
2055  else if (chocoSlot ==5){return slot[s].choco56[1];}
2056  else
2057  {
2058  FF7CHOCOBO bob;
2059  QByteArray temp;
2060  temp.fill(0,16);
2061  memcpy(&bob,temp,16);
2062  return bob;
2063  }
2064 }
2065 
2066 quint16 FF7Save::chocoStamina(int s,int chocoSlot){return slot[s].chocostaminas[chocoSlot];}
2067 quint16 FF7Save::chocoSpeed(int s,int chocoSlot)
2068 {
2069  if(chocoSlot >-1 && chocoSlot <4){return slot[s].chocobos[chocoSlot].speed;}
2070  else if (chocoSlot ==4){return slot[s].choco56[0].speed;}
2071  else if (chocoSlot ==5){return slot[s].choco56[1].speed;}
2072  else {return 0;}
2073 }
2074 quint16 FF7Save::chocoMaxSpeed(int s,int chocoSlot)
2075 {
2076  if(chocoSlot >-1 && chocoSlot <4){return slot[s].chocobos[chocoSlot].maxspeed;}
2077  else if (chocoSlot ==4){return slot[s].choco56[0].maxspeed;}
2078  else if (chocoSlot ==5){return slot[s].choco56[1].maxspeed;}
2079  else {return 0;}
2080 }
2081 quint16 FF7Save::chocoSprintSpeed(int s,int chocoSlot)
2082 {
2083  if(chocoSlot >-1 && chocoSlot <4){return slot[s].chocobos[chocoSlot].sprintspd;}
2084  else if (chocoSlot ==4){return slot[s].choco56[0].sprintspd;}
2085  else if (chocoSlot ==5){return slot[s].choco56[1].sprintspd;}
2086  else {return 0;}
2087 }
2088 quint16 FF7Save::chocoMaxSprintSpeed(int s,int chocoSlot)
2089 {
2090  if(chocoSlot >-1 && chocoSlot <4){return slot[s].chocobos[chocoSlot].maxsprintspd;}
2091  else if (chocoSlot ==4){return slot[s].choco56[0].maxsprintspd;}
2092  else if (chocoSlot ==5){return slot[s].choco56[1].maxsprintspd;}
2093  else {return 0;}
2094 }
2095 quint8 FF7Save::chocoSex(int s, int chocoSlot)
2096 {
2097  if(chocoSlot >-1 && chocoSlot <4){return slot[s].chocobos[chocoSlot].sex;}
2098  else if (chocoSlot ==4){return slot[s].choco56[0].sex;}
2099  else if (chocoSlot ==5){return slot[s].choco56[1].sex;}
2100  else {return 0;}
2101 }
2102 quint8 FF7Save::chocoType(int s, int chocoSlot)
2103 {
2104  if(chocoSlot >-1 && chocoSlot <4){return slot[s].chocobos[chocoSlot].type;}
2105  else if (chocoSlot ==4){return slot[s].choco56[0].type;}
2106  else if (chocoSlot ==5){return slot[s].choco56[1].type;}
2107  else {return 0;}
2108 }
2109 quint8 FF7Save::chocoCoop(int s, int chocoSlot)
2110 {
2111  if(chocoSlot >-1 && chocoSlot <4){return slot[s].chocobos[chocoSlot].coop;}
2112  else if (chocoSlot ==4){return slot[s].choco56[0].coop;}
2113  else if (chocoSlot ==5){return slot[s].choco56[1].coop;}
2114  else {return 0;}
2115 }
2116 quint8 FF7Save::chocoAccel(int s, int chocoSlot)
2117 {
2118  if(chocoSlot >-1 && chocoSlot <4){return slot[s].chocobos[chocoSlot].accel;}
2119  else if (chocoSlot ==4){return slot[s].choco56[0].accel;}
2120  else if (chocoSlot ==5){return slot[s].choco56[1].accel;}
2121  else {return 0;}
2122 }
2123 quint8 FF7Save::chocoIntelligence(int s, int chocoSlot)
2124 {
2125  if(chocoSlot >-1 && chocoSlot <4){return slot[s].chocobos[chocoSlot].intelligence;}
2126  else if (chocoSlot ==4){return slot[s].choco56[0].intelligence;}
2127  else if (chocoSlot ==5){return slot[s].choco56[1].intelligence;}
2128  else {return 0;}
2129 }
2130 quint8 FF7Save::chocoRaceswon(int s, int chocoSlot)
2131 {
2132  if(chocoSlot >-1 && chocoSlot <4){return slot[s].chocobos[chocoSlot].raceswon;}
2133  else if (chocoSlot ==4){return slot[s].choco56[0].raceswon;}
2134  else if (chocoSlot ==5){return slot[s].choco56[1].raceswon;}
2135  else {return 0;}
2136 }
2137 quint8 FF7Save::chocoPCount(int s, int chocoSlot)
2138 {
2139  if(chocoSlot >-1 && chocoSlot <4){return slot[s].chocobos[chocoSlot].pcount;}
2140  else if (chocoSlot ==4){return slot[s].choco56[0].pcount;}
2141  else if (chocoSlot ==5){return slot[s].choco56[1].pcount;}
2142  else {return 0;}
2143 }
2144 quint8 FF7Save::chocoPersonality(int s, int chocoSlot)
2145 {
2146  if(chocoSlot >-1 && chocoSlot <4){return slot[s].chocobos[chocoSlot].personality;}
2147  else if (chocoSlot ==4){return slot[s].choco56[0].personality;}
2148  else if (chocoSlot ==5){return slot[s].choco56[1].personality;}
2149  else {return 0;}
2150 }
2151 bool FF7Save::chocoCantMate(int s, int chocoSlot){return slot[s].chocomated& (1<<chocoSlot);}
2152 
2153 void FF7Save::setChocoStamina(int s,int chocoSlot,quint16 stamina){slot[s].chocostaminas[chocoSlot] = stamina;setFileModified(true,s);}
2154 void FF7Save::setChocoSpeed(int s,int chocoSlot,quint16 speed)
2155 {
2156  if(chocoSlot >-1 && chocoSlot <4){slot[s].chocobos[chocoSlot].speed = speed;setFileModified(true,s);}
2157  else if (chocoSlot ==4){slot[s].choco56[0].speed = speed;setFileModified(true,s);}
2158  else if (chocoSlot ==5){slot[s].choco56[1].speed = speed;setFileModified(true,s);}
2159 }
2160 void FF7Save::setChocoMaxSpeed(int s,int chocoSlot,quint16 maxspeed)
2161 {
2162  if(chocoSlot >-1 && chocoSlot <4){slot[s].chocobos[chocoSlot].maxspeed = maxspeed;setFileModified(true,s);}
2163  else if (chocoSlot ==4){slot[s].choco56[0].maxspeed = maxspeed;setFileModified(true,s);}
2164  else if (chocoSlot ==5){slot[s].choco56[1].maxspeed = maxspeed;setFileModified(true,s);}
2165 }
2166 void FF7Save::setChocoSprintSpeed(int s,int chocoSlot,quint16 sprintSpeed)
2167 {
2168  if(chocoSlot >-1 && chocoSlot <4){slot[s].chocobos[chocoSlot].sprintspd = sprintSpeed;setFileModified(true,s);}
2169  else if (chocoSlot ==4){slot[s].choco56[0].sprintspd = sprintSpeed;setFileModified(true,s);}
2170  else if (chocoSlot ==5){slot[s].choco56[1].sprintspd = sprintSpeed;setFileModified(true,s);}
2171 }
2172 void FF7Save::setChocoMaxSprintSpeed(int s,int chocoSlot,quint16 maxsprintSpeed)
2173 {
2174  if(chocoSlot >-1 && chocoSlot <4){slot[s].chocobos[chocoSlot].maxsprintspd = maxsprintSpeed;setFileModified(true,s);}
2175  else if (chocoSlot ==4){slot[s].choco56[0].maxsprintspd = maxsprintSpeed;setFileModified(true,s);}
2176  else if (chocoSlot ==5){slot[s].choco56[1].maxsprintspd = maxsprintSpeed;setFileModified(true,s);}
2177 }
2178 void FF7Save::setChocoSex(int s, int chocoSlot,quint8 value)
2179 {
2180  if(chocoSlot >-1 && chocoSlot <4){ slot[s].chocobos[chocoSlot].sex = value;setFileModified(true,s);}
2181  else if (chocoSlot ==4){ slot[s].choco56[0].sex = value;setFileModified(true,s);}
2182  else if (chocoSlot ==5){ slot[s].choco56[1].sex = value;setFileModified(true,s);}
2183 }
2184 void FF7Save::setChocoType(int s, int chocoSlot,quint8 value)
2185 {
2186  if(chocoSlot >-1 && chocoSlot <4){ slot[s].chocobos[chocoSlot].type = value;setFileModified(true,s);}
2187  else if (chocoSlot ==4){ slot[s].choco56[0].type = value;setFileModified(true,s);}
2188  else if (chocoSlot ==5){ slot[s].choco56[1].type = value;setFileModified(true,s);}
2189 }
2190 void FF7Save::setChocoCoop(int s, int chocoSlot,quint8 value)
2191 {
2192  if(chocoSlot >-1 && chocoSlot <4){ slot[s].chocobos[chocoSlot].coop = value;setFileModified(true,s);}
2193  else if (chocoSlot ==4){ slot[s].choco56[0].coop = value;setFileModified(true,s);}
2194  else if (chocoSlot ==5){ slot[s].choco56[1].coop = value;setFileModified(true,s);}
2195 }
2196 void FF7Save::setChocoAccel(int s, int chocoSlot,quint8 value)
2197 {
2198  if(chocoSlot >-1 && chocoSlot <4){ slot[s].chocobos[chocoSlot].accel = value;setFileModified(true,s);}
2199  else if (chocoSlot ==4){ slot[s].choco56[0].accel = value;setFileModified(true,s);}
2200  else if (chocoSlot ==5){ slot[s].choco56[1].accel = value;setFileModified(true,s);}
2201 }
2202 void FF7Save::setChocoIntelligence(int s, int chocoSlot,quint8 value)
2203 {
2204  if(chocoSlot >-1 && chocoSlot <4){ slot[s].chocobos[chocoSlot].intelligence = value;setFileModified(true,s);}
2205  else if (chocoSlot ==4){ slot[s].choco56[0].intelligence = value;setFileModified(true,s);}
2206  else if (chocoSlot ==5){ slot[s].choco56[1].intelligence = value;setFileModified(true,s);}
2207 }
2208 void FF7Save::setChocoRaceswon(int s, int chocoSlot,quint8 value)
2209 {
2210  if(chocoSlot >-1 && chocoSlot <4){ slot[s].chocobos[chocoSlot].raceswon = value;setFileModified(true,s);}
2211  else if (chocoSlot ==4){ slot[s].choco56[0].raceswon = value;setFileModified(true,s);}
2212  else if (chocoSlot ==5){ slot[s].choco56[1].raceswon = value;setFileModified(true,s);}
2213 }
2214 void FF7Save::setChocoPCount(int s, int chocoSlot,quint8 value)
2215 {
2216  if(chocoSlot >-1 && chocoSlot <4){ slot[s].chocobos[chocoSlot].pcount = value;setFileModified(true,s);}
2217  else if (chocoSlot ==4){ slot[s].choco56[0].pcount = value;setFileModified(true,s);}
2218  else if (chocoSlot ==5){ slot[s].choco56[1].pcount = value;setFileModified(true,s);}
2219 }
2220 void FF7Save::setChocoPersonality(int s, int chocoSlot,quint8 value)
2221 {
2222  if(chocoSlot >-1 && chocoSlot <4){ slot[s].chocobos[chocoSlot].personality = value;setFileModified(true,s);}
2223  else if (chocoSlot ==4){ slot[s].choco56[0].personality = value;setFileModified(true,s);}
2224  else if (chocoSlot ==5){ slot[s].choco56[1].personality = value;setFileModified(true,s);}
2225 }
2226 void FF7Save::setChocoCantMate(int s,int chocoSlot,bool cantMate)
2227 {
2228  if(cantMate){slot[s].chocomated |= (1 << chocoSlot);}
2229  else{slot[s].chocomated &=~(1<< chocoSlot);}
2230  setFileModified(true,s);
2231 }
2232 quint32 FF7Save::gil(int s){return slot[s].gil;}
2233 void FF7Save::setGil(int s,int gil)
2234 {
2235  if(gil<0){gil =0;}
2236  slot[s].gil = gil;
2237  setDescGil(s,gil);//Update Desc
2238  setFileModified(true,s);
2239 }
2240 quint16 FF7Save::gp (int s){return slot[s].gp;}
2241 void FF7Save::setGp(int s,int gp)
2242 {
2243  if(gp <0){gp = 0;}
2244  if(gp >65535){gp = 65535;}
2245  slot[s].gp = gp;
2246  setFileModified(true,s);
2247 }
2248 quint16 FF7Save::battles (int s){return slot[s].battles;}
2250 {
2251  if(battles <0){battles = 0;}
2252  if(battles >65535){battles = 65535;}
2253  slot[s].battles = battles;
2254  setFileModified(true,s);
2255 }
2256 quint16 FF7Save::runs (int s){return slot[s].runs;}
2257 void FF7Save::setRuns(int s,int runs)
2258 {
2259  if(runs <0){runs = 0;}
2260  if(runs >65535){runs = 65535;}
2261  slot[s].runs = runs;
2262  setFileModified(true,s);
2263 }
2264 quint8 FF7Save::party(int s,int pos){return slot[s].party[pos];}
2265 void FF7Save::setParty(int s,int pos, int new_id)
2266 {
2267  if(pos >=0 && pos <3)
2268  {
2269  if(new_id >=0 && new_id<12){slot[s].party[pos] = new_id;}
2270  else{slot[s].party[pos] =0xFF;}
2271  setFileModified(true,s);
2272  }
2273 }
2274 QString FF7Save::snowboardTime(int s, int course)
2275 {
2276  quint32 time=0;
2277  switch(course)
2278  {
2279  case 0:
2280  time = slot[s].SnowBegFastTime;
2281  break;
2282  case 1:
2283  time = slot[s].SnowExpFastTime;
2284  break;
2285  case 2:
2286  time = slot[s].SnowCrazyFastTime;
2287  break;
2288  default: break;
2289  }
2290  return QString("%1").arg(time, 8, 16, QChar('0'));
2291 }
2292 void FF7Save::setSnowboardTime(int s, int course,QString value)
2293 {
2294  switch(course)
2295  {
2296  case 0:
2297  slot[s].SnowBegFastTime= value.toInt(0,16);
2298  setFileModified(true,s);
2299  break;
2300  case 1:
2301  slot[s].SnowExpFastTime= value.toInt(0,16);
2302  setFileModified(true,s);
2303  break;
2304  case 2:
2305  slot[s].SnowCrazyFastTime= value.toInt(0,16);
2306  setFileModified(true,s);
2307  break;
2308  default: break;
2309  }
2310 }
2311 
2312 quint8 FF7Save::snowboardScore(int s, int course)
2313 {
2314  switch(course)
2315  {
2316  case 0: return slot[s].SnowBegScore; break;
2317  case 1: return slot[s].SnowExpScore; break;
2318  case 2: return slot[s].SnowCrazyScore; break;
2319  default: return 0; break;
2320  }
2321 }
2322 
2323 void FF7Save::setSnowboardScore(int s, int course,quint8 score)
2324 {
2325  switch(course)
2326  {
2327  case 0: slot[s].SnowBegScore=score; setFileModified(true,s);break;
2328  case 1: slot[s].SnowExpScore=score; setFileModified(true,s);break;
2329  case 2: slot[s].SnowCrazyScore=score; setFileModified(true,s);break;
2330  default: break;
2331  }
2332 
2333 }
2334 quint16 FF7Save::bikeHighScore(int s){return slot[s].BikeHighScore;}
2335 void FF7Save::setBikeHighScore(int s,quint16 score){slot[s].BikeHighScore = score;setFileModified(true,s);}
2336 quint16 FF7Save::battlePoints(int s){return slot[s].battlepoints;}
2337 void FF7Save::setBattlePoints(int s,quint16 bp)
2338 {
2339  if(s<0 || s>14){return;}
2340  else if(slot[s].battlepoints==bp){return;}
2341  else
2342  {
2343  slot[s].battlepoints=bp;
2344  setFileModified(true,s);
2345  }
2346 }
2347 
2348 QString FF7Save::md5sum(QString fileName, QString UserID)
2349 {
2350  QByteArray ff7file;
2351  QFile file(fileName);
2352  if(file.exists())
2353  {
2354  if(file.open(QIODevice::ReadOnly)){ff7file = file.readAll();}
2355  }
2356  if(UserID!="")
2357  {
2358  int digitcount=0;
2359  for(int i=0;i<UserID.length();i++)
2360  {
2361  if(UserID.at(i).isDigit()){digitcount ++;}
2362  }
2363  if (digitcount ==UserID.length())
2364  {//make sure the id is all digits.
2365  ff7file.append(UserID.toLatin1());//append the user's ID
2366  }
2367  }
2368  QCryptographicHash md5(QCryptographicHash::Md5);
2369  md5.addData(ff7file);
2370  return md5.result().toHex().toLower();
2371 }
2372 void FF7Save::setFileModified(bool changed,int s)
2373 {
2374  fileHasChanged=changed;
2375  if(changed){slotChanged[s]=true;}
2376  else{for(int i=0;i<15;i++){slotChanged[i]=false;}}
2377  emit(fileChanged(changed));
2378 }
2379 QVector< SubContainer > FF7Save::parseXML(QString fileName, QString metadataPath, QString UserID)
2380 {
2381  //typedef QVector< QString > SubContainer;
2382  QVector< SubContainer > vector( 10, SubContainer( 16 ) );
2383  QString Md5 = md5sum(fileName,UserID);
2384  QString timestamp = filetimestamp(fileName);
2385  QString number = fileblock(fileName); //Get file block number
2386  if(number == "-1"){/*return 0;*/} //Fail if not a number
2387  else {number = QString::number(number.toInt()+1);}
2388 
2389  QFile* file2 = new QFile(metadataPath); //Open metadata.xml
2390  if (!file2->open(QIODevice::ReadOnly)){/*return 0;*/} //If open fail, show an error message.
2391  QDomDocument doc("metadata");
2392  bool setdoc = doc.setContent(file2);
2393  file2->close();
2394  if (!setdoc){/*return 0;*/}
2395  QDomElement docElem = doc.documentElement(); //Get the root element
2396  if(docElem.tagName() != "gamestatus"){/*return 0;*/} //Check file format
2397  QDomNodeList nodeList = docElem.elementsByTagName("savefiles"); //Get savefiles node
2398  for(int ii = 0;ii < nodeList.count(); ii++) //Check each node one by one.
2399  {
2400  QDomElement el = nodeList.at(ii).toElement(); //Get the current one as QDomElement
2401  QDomNode pEntries = el.firstChild(); //Get all data for the element, by looping through all child elements
2402  int iii = 0;
2403  while(!pEntries.isNull() && iii <= 15)
2404  {
2405  QDomElement peData = pEntries.toElement();
2406  vector[ii][iii] = peData.text();
2407  if(el.attribute("block") == number)
2408  {
2409  if(iii==15){vector[ii][iii] = Md5;}
2410  else if(isSlotModified(iii)){vector[ii][iii] = timestamp;} //We check the slot mod tracker to make the time update on all modified slots
2411  else if(region(iii).isEmpty()){vector[ii][iii] = "";} //Clear timestamp for empty slot
2412  else if(vector[ii][iii] == ""){vector[ii][iii] = timestamp;}//Write the stamp (if no stamp is present and the slot isn't empty)
2413  }
2414  pEntries = pEntries.nextSibling();
2415  iii++;
2416  }
2417  }
2418  return vector;
2419 }
2420 
2421 QVector< SubContainer > FF7Save::createMetadata(QString fileName, QString UserID)
2422 {
2423  QVector< SubContainer > vector( 10, SubContainer( 16 ) );
2424  QString Md5 = md5sum(fileName,UserID);
2425 
2426  QString timestamp = filetimestamp(fileName);
2427  QString number = fileblock(fileName);//Get file block number
2428  if(number == "-1"){return vector;}
2429  //Do foreach block
2430  for(int i=0;i<10; i++)
2431  {//if i is the current number then do each slot and md5
2432  if(i == number.toInt()){ for(int j=0; j<16; j++)
2433  {
2434  if(j==15){vector[i][j] = Md5;}
2435  else if(isSlotModified(j)){vector[i][j] = timestamp;} //We check the slot mod tracker to make the time update on all modified slots
2436  else if(region(j).isEmpty()){vector[i][j] = "";} //Clear timestamp for empty slot
2437  else if(vector[i][j] == ""){vector[i][j] = timestamp;}//Write the stamp (if no stamp is present and the slot isn't empty)
2438  }}
2439  }
2440  return vector;
2441 }
2442 bool FF7Save::fixMetaData(QString fileName,QString OutPath,QString UserID)
2443 {
2444  QString UserId;//user id is not global for now
2445  if(fileName==QString("")){fileName=filename;}
2446  if(OutPath==QString(""))
2447  {
2448  QString temp= filename;
2449  temp.truncate(temp.lastIndexOf("/"));
2450  OutPath=temp;
2451  }
2452  QString Path =fileName;
2453  Path.chop(Path.length()-Path.lastIndexOf("/"));
2454  QString metadataPath = Path;
2455  metadataPath.append("/metadata.xml");
2456 
2457 
2458 
2459  QFile Metadata(metadataPath);
2460  //is a New PC saveFile then
2461  QVector< SubContainer > vector( 10, SubContainer( 16 ) );
2462 
2463  if(Metadata.exists())
2464  {//get our user id no trailing / (removed above)
2465  Path.remove(0,Path.lastIndexOf("_")+1);
2466  UserId = Path;
2467  vector = parseXML(fileName, metadataPath, UserId);
2468  }
2469  else
2470  {
2471  UserId = UserID;
2472  vector = createMetadata(fileName, UserID);
2473  }
2474  if (!Metadata.open(QIODevice::ReadWrite)){return 0;}
2475  QTextStream out (&Metadata);
2476  Metadata.seek(0);//Set pointer to the Beggining
2477  out << QString ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
2478  out << QString("<gamestatus>\n");
2479  //Do foreach block
2480  for(int i=0;i<10; i++)
2481  {
2482  out << (QString(" <savefiles block=\"%1\">\n").arg(QString::number(i+1)));
2483  //Do foreach slot
2484  for(int j=0; j<15; j++)
2485  {
2486  out << (QString(" <timestamp slot=\"%1\">%2</timestamp>\n").arg(QString::number(j+1),vector[i][j]));
2487  }
2488  out << (QString(" <signature>%1</signature>\n").arg(vector[i][15]));
2489  out << QString(" </savefiles>\n");
2490  }
2491  out << QString("</gamestatus>\n");
2492  Metadata.resize(Metadata.pos());
2493  Metadata.close();
2494  return 1;
2495 }
2496 QString FF7Save::fileName(void){return filename;}
2497 
2499 {
2500  QString number = fileName;
2501  number.remove(0,number.lastIndexOf("/")+5);//5=(/save)
2502  number.chop(4);
2503  bool isNumber = false;
2504  number = QString::number(number.toInt(&isNumber));
2505  if(isNumber){return number;}
2506  else{return "-1";}//fail if not a number.
2507 }
2509 {
2510  QFile tempFile(fileName);
2511  if(tempFile.exists()){QFileInfo file(fileName); return QString::number(file.lastModified().toMSecsSinceEpoch());}
2512  else {return "";}
2513 }
2514 QByteArray FF7Save::slotFF7Data(int s)
2515 {
2516  if(s<0 || s>14){return QByteArray(0x00);}
2517  QByteArray temp;
2518  temp.setRawData(reinterpret_cast<char *>(&slot[s]),0x10F4);
2519  return temp;
2520 }
2521 bool FF7Save::setSlotFF7Data(int s,QByteArray data)
2522 {
2523  if(s<0 || s>14){return false;}
2524  if(data.size()!=0x10F4){return false;}
2525  memcpy(&slot[s],data,0x10F4);
2526  setFileModified(true,s);
2527  return true;
2528 }
2529 
2531 {
2532  if(s<0 || s>14){return false;}
2533  slot[s] = data;
2534  setFileModified(true,s);
2535  return true;
2536 }
2537 
2538 bool FF7Save::turtleParadiseFlyerSeen(int s, int flyer)
2539 {
2540  if(s<0 || s>14){return false;}
2541  else if(flyer <0 || flyer >7){return false;}
2542  else{return ((slot[s].turtleflyers) &(1<<flyer));}
2543 }
2545 {
2546  if(s<0 || s> 14){return 0;}
2547  else{return slot[s].turtleflyers;}
2548 }
2549 
2550 void FF7Save::setTurtleParadiseFlyerSeen(int s, int flyer,bool seen)
2551 {
2552  if(s<0 || s>14){return;}
2553  else if(flyer <0 || flyer >7){return;}
2554  else
2555  {
2556  if(seen){slot[s].turtleflyers |= (1<<flyer);}
2557  else{slot[s].turtleflyers &= ~(1<<flyer);}
2558  setFileModified(true,s);
2559  }
2560 }
2561 void FF7Save::setTurtleParadiseFlyersSeen(int s,quint8 flyersSeen)
2562 {
2563  if(s<0 || s>14){return;}
2564  else
2565  {
2566  slot[s].turtleflyers = flyersSeen;
2567  setFileModified(true,s);
2568  }
2569 }
2570 bool FF7Save::itemMask1(int s, int bit)
2571 {//the Bit Number to offset.
2572  if(bit <0 || bit> 7){return false;}
2573  else{return ((slot[s].itemsmask_1)& (1<<bit) );}
2574 }
2575 void FF7Save::setItemMask1(int s, int bit, bool pickedUp)
2576 {
2577  if(s<0 || s>14){return;}
2578  else if(bit<0 || bit >7){return;}
2579  else
2580  {
2581  if(pickedUp){slot[s].itemsmask_1 |= (1<<bit);}
2582  else{slot[s].itemsmask_1 &= ~(1<<bit);}
2583  setFileModified(true,s);
2584  }
2585 }
2586 
2587 bool FF7Save::bmProgress1(int s, int bit)
2588 {//the Bit Number to offset.
2589  if(bit <0 || bit> 7){return false;}
2590  else{return ((slot[s].bm_progress1)& (1<<bit) );}
2591 }
2592 void FF7Save::setBmProgress1(int s, int bit, bool isTrue)
2593 {
2594  if(s<0 || s>14){return;}
2595  else if(bit<0 || bit >7){return;}
2596  else
2597  {
2598  if(isTrue){slot[s].bm_progress1 |= (1<<bit);}
2599  else{slot[s].bm_progress1 &= ~(1<<bit);}
2600  setFileModified(true,s);
2601  }
2602 }
2603 void FF7Save::setBmProgress1(int s, int value)
2604 {
2605  if(s<0 ||s>14){return;}
2606  else
2607  {
2608  if(value<0){value=0;}
2609  else if(value>0xFF){value=0xFF;}
2610  if(value != slot[s].bm_progress1)
2611  {
2612  slot[s].bm_progress1 = value;
2613  setFileModified(true,s);
2614  }
2615  }
2616 }
2617 bool FF7Save::bmProgress2(int s, int bit)
2618 {//the Bit Number to offset.
2619  if(bit <0 || bit> 7){return false;}
2620  else{return ((slot[s].bm_progress2)& (1<<bit) );}
2621 }
2622 void FF7Save::setBmProgress2(int s, int bit, bool isTrue)
2623 {
2624  if(s<0 || s>14){return;}
2625  else if(bit<0 || bit >7){return;}
2626  else
2627  {
2628  if(isTrue){slot[s].bm_progress2 |= (1<<bit);}
2629  else{slot[s].bm_progress2 &= ~(1<<bit);}
2630  setFileModified(true,s);
2631  }
2632 }
2633 void FF7Save::setBmProgress2(int s, int value)
2634 {
2635  if(s<0 ||s>14){return;}
2636  else
2637  {
2638  if(value<0){value=0;}
2639  else if(value>0xFF){value=0xFF;}
2640  if(value != slot[s].bm_progress3)
2641  {
2642  slot[s].bm_progress2 = value;
2643  setFileModified(true,s);
2644  }
2645  }
2646 }
2647 bool FF7Save::bmProgress3(int s, int bit)
2648 {//the Bit Number to offset.
2649  if(bit <0 || bit> 7){return false;}
2650  else{return ((slot[s].bm_progress3)& (1<<bit) );}
2651 }
2652 void FF7Save::setBmProgress3(int s, int bit, bool isTrue)
2653 {
2654  if(s<0 || s>14){return;}
2655  else if(bit<0 || bit >7){return;}
2656  else
2657  {
2658  if(isTrue){slot[s].bm_progress3 |= (1<<bit);}
2659  else{slot[s].bm_progress3 &= ~(1<<bit);}
2660  setFileModified(true,s);
2661  }
2662 }
2663 void FF7Save::setBmProgress3(int s, int value)
2664 {
2665  if(s<0 ||s>14){return;}
2666  else
2667  {
2668  if(value<0){value=0;}
2669  else if(value>0xFF){value=0xFF;}
2670  if(value != slot[s].bm_progress3)
2671  {
2672  slot[s].bm_progress3 = value;
2673  setFileModified(true,s);
2674  }
2675  }
2676 }
2677 
2678 bool FF7Save::midgarTrainFlags(int s, int bit)
2679 {//the Bit Number to offset.
2680  if(bit <0 || bit> 7){return false;}
2681  else{return ((slot[s].midgartrainflags)& (1<<bit) );}
2682 }
2683 void FF7Save::setMidgarTrainFlags(int s, int bit, bool isTrue)
2684 {
2685  if(s<0 || s>14){return;}
2686  else if(bit<0 || bit >7){return;}
2687  else
2688  {
2689  if(isTrue){slot[s].midgartrainflags |= (1<<bit);}
2690  else{slot[s].midgartrainflags &= ~(1<<bit);}
2691  setFileModified(true,s);
2692  }
2693 }
2694 void FF7Save::setMidgarTrainFlags(int s, int value)
2695 {
2696  if(s<0 ||s>14){return;}
2697  else
2698  {
2699  if(value<0){value=0;}
2700  else if(value>0xFF){value=0xFF;}
2701  if(value != slot[s].midgartrainflags)
2702  {
2703  slot[s].midgartrainflags = value;
2704  setFileModified(true,s);
2705  }
2706  }
2707 }
2708 
2709 QByteArray FF7Save::keyItems(int s)
2710 {
2711  if(s<0 || s>14){return QByteArray("\x00");}
2712  else
2713  {
2714  QByteArray temp;
2715  temp.setRawData(reinterpret_cast<char *>(&slot[s].keyitems),sizeof(slot[s].keyitems));
2716  return temp;
2717  }
2718 }
2719 bool FF7Save::keyItem(int s, int keyItem)
2720 {
2721  if(s<0 || s>14){return false;}
2722  else if(keyItem <0 || keyItem>51){return false;}
2723  else{return ((slot[s].keyitems[keyItem/8]) & (1<< (keyItem%8)));}
2724 }
2725 void FF7Save::setKeyItem(int s, int keyItem, bool pickedUp)
2726 {
2727  if(s<0 || s>14){return ;}
2728  else if(keyItem <0 || keyItem>51){return;}
2729  else
2730  {
2731  if(pickedUp){slot[s].keyitems[keyItem/8] |= (1<< (keyItem%8));}
2732  else{slot[s].keyitems[keyItem/8] &= ~(1<< (keyItem%8));}
2733  setFileModified(true,s);
2734  }
2735 
2736 }
2737 bool FF7Save::setKeyItems(int s,QByteArray data)
2738 {
2739  if(data.size() != sizeof(slot[s].keyitems)) {return false;}
2740  else
2741  {
2742  memcpy(&slot[s].keyitems,data,sizeof(slot[s].keyitems));
2743  setFileModified(true,s);
2744  return true;
2745  }
2746 }
2747 QByteArray FF7Save::unknown(int s,int z)
2748 {
2749  if(s<0 || s>14){return QByteArray(0x00);}
2750  QByteArray temp;
2751  switch(z)
2752  {
2753  case 0: temp.setRawData(0x00,1); break;
2754  case 1: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_1),sizeof(slot[s].z_1)); break;
2755  case 2: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_2),sizeof(slot[s].z_2)); break;
2756  case 3: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_3),sizeof(slot[s].z_3)); break;
2757  case 4: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_4),sizeof(slot[s].z_4)); break;
2758  case 5: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_5),sizeof(slot[s].z_5)); break;
2759  case 6: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_6),sizeof(slot[s].z_6)); break;
2760  case 7: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_7),sizeof(slot[s].z_7)); break;
2761  case 8: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_8),sizeof(slot[s].z_8)); break;
2762  case 9: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_9),sizeof(slot[s].z_9)); break;
2763  case 10: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_10),sizeof(slot[s].z_10)); break;
2764  case 11: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_11),sizeof(slot[s].z_11)); break;
2765  case 12: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_12),sizeof(slot[s].z_12)); break;
2766  case 13: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_13),sizeof(slot[s].z_13)); break;
2767  case 14: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_14),sizeof(slot[s].z_14)); break;
2768  case 15: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_15),sizeof(slot[s].z_15)); break;
2769  case 16: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_16),sizeof(slot[s].z_16)); break;
2770  case 17: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_17),sizeof(slot[s].z_17)); break;
2771  case 18: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_18),sizeof(slot[s].z_18)); break;
2772  case 19: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_19),sizeof(slot[s].z_19)); break;
2773  case 20: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_20),sizeof(slot[s].z_20)); break;
2774  case 21: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_21),sizeof(slot[s].z_21)); break;
2775  case 22: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_22),sizeof(slot[s].z_22)); break;
2776  case 23: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_23),sizeof(slot[s].z_23)); break;
2777  case 24: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_24),sizeof(slot[s].z_24)); break;
2778  case 25: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_25),sizeof(slot[s].z_25)); break;
2779  case 26: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_26),sizeof(slot[s].z_26)); break;
2780  case 27: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_27),sizeof(slot[s].z_27)); break;
2781  case 28: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_28),sizeof(slot[s].z_28)); break;
2782  case 29: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_29),sizeof(slot[s].z_29)); break;
2783  case 30: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_30),sizeof(slot[s].z_30)); break;
2784  case 31: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_31),sizeof(slot[s].z_31)); break;
2785  case 32: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_32),sizeof(slot[s].z_32)); break;
2786  case 33: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_33),sizeof(slot[s].z_33)); break;
2787  case 34: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_34),sizeof(slot[s].z_34)); break;
2788  case 35: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_35),sizeof(slot[s].z_35)); break;
2789  case 36: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_36),sizeof(slot[s].z_36)); break;
2790  case 37: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_37),sizeof(slot[s].z_37)); break;
2791  case 38: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_38),sizeof(slot[s].z_38)); break;
2792  case 39: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_39),sizeof(slot[s].z_39)); break;
2793  case 40: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_40),sizeof(slot[s].z_40)); break;
2794  case 41: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_41),sizeof(slot[s].z_41)); break;
2795  case 42: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_42),sizeof(slot[s].z_42)); break;
2796  case 43: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_43),sizeof(slot[s].z_43)); break;
2797  case 44: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_44),sizeof(slot[s].z_44)); break;
2798  case 45: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_45),sizeof(slot[s].z_45)); break;
2799  case 46: temp.setRawData(reinterpret_cast<char *>(&slot[s].z_46),sizeof(slot[s].z_46)); break;
2800  default: temp.setRawData(0x00,1); break;
2801  }
2802  return temp;
2803 }
2804 
2805 bool FF7Save::setUnknown(int s,int z,QByteArray data)
2806 {
2807  if(s<0 || s>14){return false;}
2808  bool result;
2809  switch(z)
2810  {
2811  case 0: result=false; break;
2812  case 1:
2813  if(data.size() != sizeof(slot[s].z_1)) {result=false; break;}
2814  else{memcpy(&slot[s].z_1,data,sizeof(slot[s].z_1)); result=true;break;}
2815  case 2:
2816  if(data.size() != sizeof(slot[s].z_2)) {result=false; break;}
2817  else{memcpy(&slot[s].z_2,data,sizeof(slot[s].z_2)); result=true;break;}
2818  case 3:
2819  if(data.size() != sizeof(slot[s].z_3)) {result=false; break;}
2820  else{memcpy(&slot[s].z_3,data,sizeof(slot[s].z_3)); result=true;break;}
2821  case 4:
2822  if(data.size() != sizeof(slot[s].z_4)) {result=false; break;}
2823  else{memcpy(&slot[s].z_4,data,sizeof(slot[s].z_4)); result=true;break;}
2824  case 5:
2825  if(data.size() != sizeof(slot[s].z_5)) {result=false; break;}
2826  else{memcpy(&slot[s].z_5,data,sizeof(slot[s].z_5)); result=true;break;}
2827  case 6:
2828  if(data.size() != sizeof(slot[s].z_6)) {result=false; break;}
2829  else{memcpy(&slot[s].z_6,data,sizeof(slot[s].z_6)); result=true;break;}
2830  case 7:
2831  if(data.size() != sizeof(slot[s].z_7)) {result=false; break;}
2832  else{memcpy(&slot[s].z_7,data,sizeof(slot[s].z_7)); result=true;break;}
2833  case 8:
2834  if(data.size() != sizeof(slot[s].z_8)) {result=false; break;}
2835  else{memcpy(&slot[s].z_8,data,sizeof(slot[s].z_8)); result=true;break;}
2836  case 9:
2837  if(data.size() != sizeof(slot[s].z_9)) {result=false; break;}
2838  else{memcpy(&slot[s].z_9,data,sizeof(slot[s].z_9)); result=true;break;}
2839  case 10:
2840  if(data.size() != sizeof(slot[s].z_10)) {result=false; break;}
2841  else{memcpy(&slot[s].z_10,data,sizeof(slot[s].z_10)); result=true;break;}
2842  case 11:
2843  if(data.size() != sizeof(slot[s].z_11)) {result=false; break;}
2844  else{memcpy(&slot[s].z_11,data,sizeof(slot[s].z_11)); result=true;break;}
2845  case 12:
2846  if(data.size() != sizeof(slot[s].z_12)) {result=false; break;}
2847  else{memcpy(&slot[s].z_12,data,sizeof(slot[s].z_12)); result=true;break;}
2848  case 13:
2849  if(data.size() != sizeof(slot[s].z_13)) {result=false; break;}
2850  else{memcpy(&slot[s].z_13,data,sizeof(slot[s].z_13)); result=true;break;}
2851  case 14:
2852  if(data.size() != sizeof(slot[s].z_14)) {result=false; break;}
2853  else{memcpy(&slot[s].z_14,data,sizeof(slot[s].z_14)); result=true;break;}
2854  case 15:
2855  if(data.size() != sizeof(slot[s].z_15)) {result=false; break;}
2856  else{memcpy(&slot[s].z_15,data,sizeof(slot[s].z_15)); result=true;break;}
2857  case 16:
2858  if(data.size() != sizeof(slot[s].z_16)) {result=false; break;}
2859  else{memcpy(&slot[s].z_16,data,sizeof(slot[s].z_16)); result=true;break;}
2860  case 17:
2861  if(data.size() != sizeof(slot[s].z_17)) {result=false; break;}
2862  else{memcpy(&slot[s].z_17,data,sizeof(slot[s].z_17)); result=true;break;}
2863  case 18:
2864  if(data.size() != sizeof(slot[s].z_18)) {result=false; break;}
2865  else{memcpy(&slot[s].z_18,data,sizeof(slot[s].z_18)); result=true;break;}
2866  case 19:
2867  if(data.size() != sizeof(slot[s].z_19)) {result=false; break;}
2868  else{memcpy(&slot[s].z_19,data,sizeof(slot[s].z_19)); result=true;break;}
2869  case 20:
2870  if(data.size() != sizeof(slot[s].z_20)) {result=false; break;}
2871  else{memcpy(&slot[s].z_20,data,sizeof(slot[s].z_20)); result=true;break;}
2872  case 21:
2873  if(data.size() != sizeof(slot[s].z_21)) {result=false; break;}
2874  else{memcpy(&slot[s].z_21,data,sizeof(slot[s].z_21)); result=true;break;}
2875  case 22:
2876  if(data.size() != sizeof(slot[s].z_22)) {result=false; break;}
2877  else{memcpy(&slot[s].z_22,data,sizeof(slot[s].z_22)); result=true;break;}
2878  case 23:
2879  if(data.size() != sizeof(slot[s].z_23)) {result=false; break;}
2880  else{memcpy(&slot[s].z_23,data,sizeof(slot[s].z_23)); result=true;break;}
2881  case 24:
2882  if(data.size() != sizeof(slot[s].z_24)) {result=false; break;}
2883  else{memcpy(&slot[s].z_24,data,sizeof(slot[s].z_24)); result=true;break;}
2884  case 25:
2885  if(data.size() != sizeof(slot[s].z_25)) {result=false; break;}
2886  else{memcpy(&slot[s].z_25,data,sizeof(slot[s].z_25)); result=true;break;}
2887  case 26:
2888  if(data.size() != sizeof(slot[s].z_26)) {result=false; break;}
2889  else{memcpy(&slot[s].z_26,data,sizeof(slot[s].z_26)); result=true;break;}
2890  case 27:
2891  if(data.size() != sizeof(slot[s].z_27)) {result=false; break;}
2892  else{memcpy(&slot[s].z_27,data,sizeof(slot[s].z_27)); result=true;break;}
2893  case 28:
2894  if(data.size() != sizeof(slot[s].z_28)) {result=false; break;}
2895  else{memcpy(&slot[s].z_28,data,sizeof(slot[s].z_28)); result=true;break;}
2896  case 29:
2897  if(data.size() != sizeof(slot[s].z_29)) {result=false; break;}
2898  else{memcpy(&slot[s].z_29,data,sizeof(slot[s].z_29)); result=true;break;}
2899  case 30:
2900  if(data.size() != sizeof(slot[s].z_30)) {result=false; break;}
2901  else{memcpy(&slot[s].z_30,data,sizeof(slot[s].z_30)); result=true;break;}
2902  case 31:
2903  if(data.size() != sizeof(slot[s].z_31)) {result=false; break;}
2904  else{memcpy(&slot[s].z_31,data,sizeof(slot[s].z_31)); result=true;break;}
2905  case 32:
2906  if(data.size() != sizeof(slot[s].z_32)) {result=false; break;}
2907  else{memcpy(&slot[s].z_32,data,sizeof(slot[s].z_32)); result=true;break;}
2908  case 33:
2909  if(data.size() != sizeof(slot[s].z_33)) {result=false; break;}
2910  else{memcpy(&slot[s].z_33,data,sizeof(slot[s].z_33)); result=true;break;}
2911  case 34:
2912  if(data.size() != sizeof(slot[s].z_34)) {result=false; break;}
2913  else{memcpy(&slot[s].z_34,data,sizeof(slot[s].z_34)); result=true;break;}
2914  case 35:
2915  if(data.size() != sizeof(slot[s].z_35)) {result=false; break;}
2916  else{memcpy(&slot[s].z_35,data,sizeof(slot[s].z_35)); result=true;break;}
2917  case 36:
2918  if(data.size() != sizeof(slot[s].z_36)) {result=false; break;}
2919  else{memcpy(&slot[s].z_36,data,sizeof(slot[s].z_36)); result=true;break;}
2920  case 37:
2921  if(data.size() != sizeof(slot[s].z_37)) {result=false; break;}
2922  else{memcpy(&slot[s].z_37,data,sizeof(slot[s].z_37)); result=true;break;}
2923  case 38:
2924  if(data.size() != sizeof(slot[s].z_38)) {result=false; break;}
2925  else{memcpy(&slot[s].z_38,data,sizeof(slot[s].z_38)); result=true;break;}
2926  case 39:
2927  if(data.size() != sizeof(slot[s].z_39)) {result=false; break;}
2928  else{memcpy(&slot[s].z_39,data,sizeof(slot[s].z_39)); result=true;break;}
2929  case 40:
2930  if(data.size() != sizeof(slot[s].z_40)) {result=false; break;}
2931  else{memcpy(&slot[s].z_40,data,sizeof(slot[s].z_40)); result=true;break;}
2932  case 41:
2933  if(data.size() != sizeof(slot[s].z_41)) {result=false; break;}
2934  else{memcpy(&slot[s].z_41,data,sizeof(slot[s].z_41)); result=true;break;}
2935  case 42:
2936  if(data.size() != sizeof(slot[s].z_42)) {result=false; break;}
2937  else{memcpy(&slot[s].z_42,data,sizeof(slot[s].z_42)); result=true;break;}
2938  case 43:
2939  if(data.size() != sizeof(slot[s].z_43)) {result=false; break;}
2940  else{memcpy(&slot[s].z_43,data,sizeof(slot[s].z_43)); result=true;break;}
2941  case 44:
2942  if(data.size() != sizeof(slot[s].z_44)) {result=false; break;}
2943  else{memcpy(&slot[s].z_44,data,sizeof(slot[s].z_44)); result=true;break;}
2944  case 45:
2945  if(data.size() != sizeof(slot[s].z_45)) {result=false; break;}
2946  else{memcpy(&slot[s].z_45,data,sizeof(slot[s].z_45)); result=true;break;}
2947  case 46:
2948  if(data.size() != sizeof(slot[s].z_46)) {result=false; break;}
2949  else{memcpy(&slot[s].z_46,data,sizeof(slot[s].z_46)); result=true;break;}
2950  default: result=false; break;
2951  }
2952  setFileModified(true,s);
2953  return result;
2954 }
2955 bool FF7Save::soundMode(int s){return (slot[s].options & (1<<0));}
2956 
2957 void FF7Save::setSoundMode(int s,int mode)
2958 {
2959  if(mode !=soundMode(s))
2960  {
2961  switch(mode)
2962  {
2963  case SOUND_MONO: slot[s].options &= ~(1<<0); break;
2964  case SOUND_STEREO: slot[s].options |= (1<<0); break;
2965  default: slot[s].options &= ~(1<<0) ; break;
2966  }
2967  setFileModified(true,s);
2968  }
2969 }
2970 void FF7Save::setSoundMode(int s,bool mode)
2971 {
2972  if(!(mode && soundMode(s)))
2973  {
2974  if(mode){slot[s].options |= (1<<0);}
2975  else{slot[s].options &=~(1<<0);}
2976  setFileModified(true,s);
2977  }
2978 }
2979 
2980 bool FF7Save::controlMode(int s){return (slot[s].options& (1<<2));}
2981 void FF7Save::setControlMode(int s, int mode)
2982 {
2983  if(mode !=controlMode(s))
2984  {
2985  switch(mode)
2986  {
2987  case CONTROL_NORMAL: slot[s].options &= ~(1<<2); break;
2988  case CONTROL_CUSTOM: slot[s].options |= (1<<2); break;
2989  default: slot[s].options &= ~(1<<2) ; break;
2990  }
2991  setFileModified(true,s);
2992  }
2993 }
2994 
2995 void FF7Save::setControlMode(int s, bool mode)
2996 {
2997  if(!(mode && controlMode(s)))
2998  {
2999  if(mode){slot[s].options |= (1<<2);}
3000  else{slot[s].options &=~(1<<2);}
3001  setFileModified(true,s);
3002  }
3003 }
3004 bool FF7Save::cursorMode(int s){return (slot[s].options&(1<<4));}
3005 
3006 void FF7Save::setCursorMode(int s, int mode)
3007 {
3008  if(!(mode && cursorMode(s)))
3009  {
3010  switch(mode)
3011  {
3012  case CURSOR_INITIAL: slot[s].options &= ~(1<<4); break;
3013  case CURSOR_MEMORY: slot[s].options |= (1<<4); break;
3014  default: slot[s].options &= ~(1<<2) ; break;
3015  }
3016  setFileModified(true,s);
3017  }
3018 }
3019 void FF7Save::setCursorMode(int s, bool mode)
3020 {
3021  if(mode != cursorMode(s))
3022  {
3023  if(mode){slot[s].options |= (1<<4);}
3024  else{slot[s].options &=~(1<<4);}
3025  setFileModified(true,s);
3026  }
3027 }
3029 {
3030  if( (slot[s].options &(1<<6))){return 1;}
3031  else if((slot[s].options &(1<<7))){return 2;}
3032  else{return 0;}
3033 }
3034 
3035 void FF7Save::setAtbMode(int s, int mode)
3036 {
3037  if(mode != atbMode(s))
3038  {
3039  switch(mode)
3040  {
3041  case ATB_ACTIVE: slot[s].options &=~(1<<6); slot[s].options&=~(1<<7); break;
3042  case ATB_RECOMMENED: slot[s].options |= (1<<6); slot[s].options&= ~(1<<7); break;
3043  case ATB_WAIT: slot[s].options &= ~(1<<6); slot[s].options |= (1<<7); break;
3044  default:slot[s].options &=~(1<<6); slot[s].options&= ~(1<<7); break;
3045  };
3046  setFileModified(true,s);
3047  }
3048 }
3049 bool FF7Save::cameraMode(int s){return (slot[s].options&(1<<8));}
3050 
3051 void FF7Save::setCameraMode(int s, int mode)
3052 {
3053  if(mode != cameraMode(s))
3054  {
3055  switch(mode)
3056  {
3057  case CAMERA_AUTO: slot[s].options &= ~(1<<8); break;
3058  case CAMERA_FIXED: slot[s].options |= (1<<8); break;
3059  }
3060  setFileModified(true,s);
3061  }
3062 }
3063 void FF7Save::setCameraMode(int s, bool mode)
3064 {
3065  if(!(mode && cameraMode(s)))
3066  {
3067  if(mode){slot[s].options |= (1<<8);}
3068  else{slot[s].options &=~(1<<8);}
3069  setFileModified(true,s);
3070  }
3071 }
3073 {
3074  if ( (slot[s].options&(1<<10)) && (slot[s].options&(1<<11))){return 3;}
3075  if ((slot[s].options&(1<<10)) && (slot[s].options&(1<<12))){return 5;}
3076  else if(slot[s].options&(1<<10)){return 1;}
3077  else if((slot[s].options&(1<<11))){return 2;}
3078  else if((slot[s].options&(1<<12))){return 4;}
3079  else{return 0;}
3080 }
3081 
3082 void FF7Save::setMagicOrder(int s, int order)
3083 {
3084  if(order != magicOrder(s))
3085  switch(order)
3086  {
3087  case MAGIC_RAI: slot[s].options &=~(1<<10); slot[s].options &=~(1<<11); slot[s].options &= ~(1<<12); break;
3088  case MAGIC_RIA: slot[s].options |=(1<<10); slot[s].options &=~(1<<11); slot[s].options &= ~(1<<12); break;
3089  case MAGIC_AIR: slot[s].options &=~(1<<10); slot[s].options |=(1<<11); slot[s].options &= ~(1<<12); break;
3090  case MAGIC_ARI: slot[s].options |=(1<<10); slot[s].options |=(1<<11); slot[s].options &= ~(1<<12); break;
3091  case MAGIC_IRA: slot[s].options &=~(1<<10); slot[s].options &=~(1<<11); slot[s].options |= (1<<12); break;
3092  case MAGIC_IAR: slot[s].options |=(1<<10); slot[s].options &=~(1<<11); slot[s].options |= (1<<12); break;
3093  default: slot[s].options &=~(1<<10); slot[s].options &=~(1<<11); slot[s].options &= ~(1<<12); break;
3094  }
3095  setFileModified(true,s);
3096 }
3097 
3098 bool FF7Save::battleHelp(int s){return ((slot[s].options)&(1<<14));}
3099 
3100 void FF7Save::setBattleHelp(int s, bool shown)
3101 {
3102  if(!(shown && battleHelp(s)))
3103  {
3104  if(shown){slot[s].options |=(1<<14);}
3105  else{slot[s].options &= ~(1<<14);}
3106  setFileModified(true,s);
3107  }
3108 }
3109 
3110 int FF7Save::battleSpeed(int s){return slot[s].battlespeed;}
3111 void FF7Save::setBattleSpeed(int s, int speed)
3112 {
3113  if(speed != slot[s].battlespeed)
3114  {
3115  if(speed<0 || speed>255){speed=0;}
3116  else{slot[s].battlespeed=speed;}
3117  setFileModified(true,s);
3118  }
3119 }
3120 
3121 int FF7Save::messageSpeed(int s){return slot[s].fieldmspeed;}
3122 void FF7Save::setMessageSpeed(int s, int speed)
3123 {
3124  if(speed != slot[s].fieldmspeed)
3125  {
3126  if(speed<0 || speed>255){speed=0;}
3127  else{slot[s].fieldmspeed=speed;}
3128  setFileModified(true,s);
3129  }
3130 }
3131 
3132 int FF7Save::battleMessageSpeed(int s){return slot[s].battlemspeed;}
3133 void FF7Save::setBattleMessageSpeed(int s, int speed)
3134 {
3135  if(speed != slot[s].battlemspeed)
3136  {
3137  if(speed<0 || speed>255){speed=0;}
3138  else{slot[s].battlemspeed=speed;}
3139  setFileModified(true,s);
3140  }
3141 }
3142 bool FF7Save::fieldHelp(int s){return ((slot[s].field_help)&(1<<0));}
3143 void FF7Save::setFieldHelp(int s, bool shown)
3144 {
3145  if(!(shown && fieldHelp(s)))
3146  {
3147  if(shown){slot[s].field_help |= (1<<0);}
3148  else{slot[s].field_help &= ~(1<<0);}
3149  setFileModified(true,s);
3150  }
3151 }
3152 bool FF7Save::battleTargets(int s){return ((slot[s].tut_sub)&(1<<6));}
3153 void FF7Save::setBattleTargets(int s, bool shown)
3154 {
3155  if(!(shown &&battleTargets(s)))
3156  {
3157  if(shown){slot[s].tut_sub |= (1<<6);}
3158  else{slot[s].tut_sub &= ~(1<<6);}
3159  setFileModified(true,s);
3160  }
3161 }
3162 
3163 quint16 FF7Save::options(int s){return slot[s].options;}
3164 void FF7Save::setOptions(int s, int opt)
3165 {
3166  if(opt != options(s))
3167  {
3168  slot[s].options= opt;
3169  setFileModified(true,s);
3170  }
3171 }
3173 {
3174  QByteArray temp;
3175  for(int i=0;i<16;i++){temp.append(slot[s].controller_map[i]);}
3176  return temp;
3177 }
3178 quint8 FF7Save::controllerMapping(int s, int action){return slot[s].controller_map[action];}
3179 
3180 void FF7Save::setControllerMapping(int s,QByteArray map)
3181 {
3182  if(map.length()>16){map.chop(16);}
3183  if(map != controllerMapping(s))
3184  {
3185  memcpy(&slot[s].controller_map,map,16);
3186  setFileModified(true,s);
3187  }
3188 }
3189 void FF7Save::setControllerMapping(int s, int action, int button)
3190 {
3191  if(button<0 || button >15){return;}
3192  else
3193  {
3194  if(slot[s].controller_map[action] != button)
3195  {
3196  slot[s].controller_map[action]= button;
3197  setFileModified(true,s);
3198  }
3199  }
3200 }
3201 bool FF7Save::phsVisible(int s, int who)
3202 {
3203  if(s<0 || s>14){return false;}
3204  if(who<0 || who>8){return false;}
3205  else{return ((slot[s].phsvisible) & (1<<who));}
3206 }
3207 void FF7Save::setPhsVisible(int s, int who, bool checked)
3208 {
3209  if(s<0 || s>14){return;}
3210  else if(who<0 || who >8){return;}
3211  else
3212  {
3213  if(checked){ slot[s].phsvisible |= (1<<who);}
3214  else {slot[s].phsvisible &= ~(1<<who);}
3215  setFileModified(true,s);
3216  }
3217 }
3218 void FF7Save::setPhsVisible(int s, quint16 phs_visible)
3219 {
3220  if(s<0 || s>14){return;}
3221  if(phs_visible!=slot[s].phsvisible)
3222  {
3223  slot[s].phsvisible=phs_visible;
3224  setFileModified(true,s);
3225  }
3226 }
3227 quint16 FF7Save::phsVisible(int s)
3228 {
3229  if(s<0 || s>14){return 0;}
3230  else{return slot[s].phsvisible;}
3231 }
3232 
3233 bool FF7Save::phsAllowed(int s, int who)
3234 {
3235  if(s<0 || s>14){return false;}
3236  if(who<0 || who>8){return false;}
3237  else{return ((slot[s].phsallowed) & (1<<who));}
3238 }
3239 quint16 FF7Save::phsAllowed(int s)
3240 {
3241  if(s<0 || s>14){return 0;}
3242  else{return slot[s].phsallowed;}
3243 }
3244 
3245 void FF7Save::setPhsAllowed(int s, int who, bool checked)
3246 {
3247  if(s<0 || s>14){return;}
3248  else if(who<0 || who >8){return;}
3249  else
3250  {
3251  if(checked){ slot[s].phsallowed |= (1<<who);}
3252  else {slot[s].phsallowed &= ~(1<<who);}
3253  setFileModified(true,s);
3254  }
3255 }
3256 void FF7Save::setPhsAllowed(int s, quint16 phs_visible)
3257 {
3258  if(s<0 || s>14){return;}
3259  if(phs_visible!=slot[s].phsallowed)
3260  {
3261  slot[s].phsallowed=phs_visible;
3262  setFileModified(true,s);
3263  }
3264 }
3265 bool FF7Save::menuVisible(int s, int index)
3266 {
3267  if(s<0 || s>14){return false;}
3268  if(index<0 || index>9){return false;}
3269  else{return ((slot[s].menu_visible) & (1<<index));}
3270 }
3271 void FF7Save::setMenuVisible(int s, int index, bool checked)
3272 {
3273  if(s<0 || s>14){return;}
3274  else if(index<0 || index >9){return;}
3275  else
3276  {
3277  if(checked){ slot[s].menu_visible |= (1<<index);}
3278  else {slot[s].menu_visible &= ~(1<<index);}
3279  setFileModified(true,s);
3280  }
3281 }
3282 void FF7Save::setMenuVisible(int s, quint16 menu_visible)
3283 {
3284  if(s<0 || s>14){return;}
3285  if(menu_visible!=slot[s].menu_visible)
3286  {
3287  slot[s].menu_visible=menu_visible;
3288  setFileModified(true,s);
3289  }
3290 }
3291 quint16 FF7Save::menuVisible(int s)
3292 {
3293  if(s<0 || s>14){return 0;}
3294  else{return slot[s].menu_visible;}
3295 }
3296 
3297 bool FF7Save::menuLocked(int s, int index)
3298 {
3299  if(s<0 || s>14){return false;}
3300  if(index<0 || index>9){return false;}
3301  else{return ((slot[s].menu_locked) & (1<<index));}
3302 }
3303 void FF7Save::setMenuLocked(int s, int index, bool checked)
3304 {
3305  if(s<0 || s>14){return;}
3306  else if(index<0 || index >9){return;}
3307  else
3308  {
3309  if(checked){slot[s].menu_locked |= (1<<index);}
3310  else {slot[s].menu_locked &= ~(1<<index);}
3311  setFileModified(true,s);
3312  }
3313 }
3314 void FF7Save::setMenuLocked(int s, quint16 menu_locked)
3315 {
3316  if(s<0 || s>14){return;}
3317  if(menu_locked!=slot[s].menu_locked)
3318  {
3319  slot[s].menu_locked=menu_locked;
3320  setFileModified(true,s);
3321  }
3322 }
3323 quint16 FF7Save::menuLocked(int s)
3324 {
3325  if(s<0 || s>14){return 0;}
3326  else{return slot[s].menu_locked;}
3327 }
3328 quint16 FF7Save::locationId(int s)
3329 {
3330  if(s<0 || s>14){return 0;}
3331  else{return slot[s].locationid;}
3332 }
3333 
3334 void FF7Save::setLocationId(int s, quint16 locationID)
3335 {
3336  if(s<0 || s>14){return;}
3337  else if (locationID == locationId(s)){return;}
3338  else
3339  {
3340  slot[s].locationid = locationID;
3341  setFileModified(true,s);
3342  }
3343 }
3344 quint16 FF7Save::mapId(int s)
3345 {
3346  if(s<0 || s>14){return 0;}
3347  else{return slot[s].mapid;}
3348 }
3349 
3350 void FF7Save::setMapId(int s, quint16 mapID)
3351 {
3352  if(s<0 || s>14){return;}
3353  else if (mapID == mapId(s)){return;}
3354  else
3355  {
3356  slot[s].mapid = mapID;
3357  setFileModified(true,s);;
3358  }
3359 }
3360 qint16 FF7Save::locationX(int s)
3361 {
3362  if(s<0 || s>14){return 0;}
3363  else{return slot[s].coord.x;}
3364 }
3365 
3366 void FF7Save::setLocationX(int s, qint16 x)
3367 {
3368  if(s<0 || s>14){return;}
3369  else if (x == locationX(s)){return;}
3370  else
3371  {
3372  slot[s].coord.x = x;
3373  setFileModified(true,s);
3374  }
3375 }
3376 qint16 FF7Save::locationY(int s)
3377 {
3378  if(s<0 || s>14){return 0;}
3379  else{return slot[s].coord.y;}
3380 }
3381 
3382 void FF7Save::setLocationY(int s, qint16 y)
3383 {
3384  if(s<0 || s>14){return;}
3385  else if (y == locationY(s)){return;}
3386  else
3387  {
3388  slot[s].coord.y = y;
3389  setFileModified(true,s);
3390  }
3391 }
3392 quint16 FF7Save::locationT(int s)
3393 {
3394  if(s<0 || s>14){return 0;}
3395  else{return slot[s].coord.t;}
3396 }
3397 
3398 void FF7Save::setLocationT(int s, quint16 t)
3399 {
3400  if(s<0 || s>14){return;}
3401  else if (t == locationT(s)){return;}
3402  else
3403  {
3404  slot[s].coord.t = t;
3405  setFileModified(true,s);
3406  }
3407 }
3408 quint8 FF7Save::locationD(int s)
3409 {
3410  if(s<0 || s>14){return 0;}
3411  else{return slot[s].coord.d;}
3412 }
3413 
3414 void FF7Save::setLocationD(int s, quint8 d)
3415 {
3416  if(s<0 || s>14){return;}
3417  else if (d == locationD(s)){return;}
3418  else
3419  {
3420  slot[s].coord.d = d;
3421  setFileModified(true,s);
3422  }
3423 }
3424 
3425 quint16 FF7Save::condorFunds(int s)
3426 {
3427  if(s<0 || s>14){return 0;}
3428  else
3429  {
3430  return slot[s].condorfunds;
3431  }
3432 }
3433 void FF7Save::setCondorFunds(int s,quint16 value)
3434 {
3435  if(value==condorFunds(s)){return;}
3436  else
3437  {
3438  slot[s].condorfunds=value;
3439  setFileModified(true,s);
3440  }
3441 }
3442 quint8 FF7Save::condorWins(int s)
3443 {
3444  if(s<0 || s>14){return 0;}
3445  else{return slot[s].condorwins;}
3446 }
3447 void FF7Save::setCondorWins(int s,quint8 wins)
3448 {
3449  if(wins ==condorWins(s)){return;}
3450  else{slot[s].condorwins = wins;setFileModified(true,s);}
3451 }
3453 {
3454  if(s<0 || s>14){return 0;}
3455  else{return slot[s].condorlosses;}
3456 }
3457 void FF7Save::setCondorLosses(int s, quint8 losses)
3458 {
3459  if(losses ==condorLosses(s)){return;}
3460  else{slot[s].condorlosses = losses;setFileModified(true,s);}
3461 }
3462 
3463 QList<FF7CHOCOBO> FF7Save::chocobos(int s)
3464 {
3465  QList<FF7CHOCOBO> chocos;
3466  for(int i=0;i<6;i++){chocos.append(chocobo(s,i));}
3467  return chocos;
3468 }
3469 
3470 QList<quint16> FF7Save::chocobosStaminas(int s)
3471 {
3472  QList<quint16> stamina;
3473  for(int i=0;i<6;i++){stamina.append(this->chocoStamina(s,i));}
3474  return stamina;
3475 }
3476 
3477 QList<QString> FF7Save::chocobosNames (int s)
3478 {
3479  QList<QString> names;
3480  for(int i=0;i<6;i++){names.append(chocoName(s,i));}
3481  return names;
3482 }
3483 QList<bool> FF7Save::chocoboCantMates(int s)
3484 {
3485  QList<bool> mates;
3486  for(int i=0;i<6;i++){mates.append(chocoCantMate(s,i));}
3487  return mates;
3488 }
3490 {
3491  if(s<0 ||s>14){return 0;}
3492  else{return slot[s].stables;}
3493 }
3494 void FF7Save::setStablesOwned(int s,qint8 value)
3495 {
3496  if(s<0 ||s>14){return;}
3497  else if(value<0 || value>6){return;}
3498  else{slot[s].stables =value;setFileModified(true,s);}
3499 }
3500 
3502 {
3503  if(s<0 ||s>14){return 0;}
3504  else{return slot[s].stablesoccupied;}
3505 }
3506 void FF7Save::setStablesOccupied(int s,qint8 value)
3507 {
3508  if(s<0 ||s>14){return;}
3509  else if(value<0 || value>6){return;}
3510  else{slot[s].stablesoccupied =value;setFileModified(true,s);}
3511 }
3512 
3514 {
3515  if(s<0 ||s>14){return 0;}
3516  else{return slot[s].chocobomask;}
3517 }
3518 
3519 void FF7Save::setStableMask(int s,qint8 value)
3520 {
3521  if(s<0 ||s>14){return;}
3522  else{slot[s].chocobomask =value;setFileModified(true,s);}
3523 }
3524 
3525 QList<qint8> FF7Save::chocoboPens(int s)
3526 {
3527  QList<qint8> pens;
3528  for(int i=0;i<4;i++){pens.append(slot[s].pennedchocos[i]);}
3529  return pens;
3530 }
3531 qint8 FF7Save::chocoboPen(int s,int pen)
3532 {
3533  if(s<0 || s>14 || pen<0 || pen>3){return 0;}
3534  else{return slot[s].pennedchocos[pen];}
3535 }
3536 void FF7Save::setChocoboPen(int s,int pen,int value)
3537 {
3538  if(s<0 || s>14 || pen<0 || pen>3 || value<0 || value>8){return;}
3539  else{slot[s].pennedchocos[pen]=value;setFileModified(true,s);
3540 }
3541 }
3543 {
3544  if(s<0 || s>14){return 0;}
3545  else{
3546  qint32 seconds = slot[s].timer[0] |(slot[s].timer[1] << 8) | (slot[s].timer[2]<<16);
3547  return seconds;
3548  }
3549 }
3550 void FF7Save::setCountdownTimer(int s, quint32 time)
3551 {
3552  if(s<0 ||s>14){return;}
3553  else
3554  {
3555  slot[s].timer[0]=(time & 0xff);
3556  slot[s].timer[1]=((time & 0xff00) >> 8);
3557  slot[s].timer[2]=((time & 0xff0000) >> 16);
3558  setFileModified(true,s);
3559  }
3560 }
3562 {
3563  if(s<0 ||s>14){return false;}
3564  else{return (slot[s].seenpandora&(1<<0));}
3565 }
3566 void FF7Save::setSeenPandorasBox(int s,bool seen)
3567 {
3568  if(seen){slot[s].seenpandora |= (1<<0);}
3569  else{slot[s].seenpandora &= ~(1<<0);}
3570  setFileModified(true,s);
3571 }
3572 quint16 FF7Save::steps(int s)
3573 {
3574  if(s<0 || s>14){return 0;}
3575  else{return slot[s].steps;}
3576 }
3577 void FF7Save::setSteps(int s,int steps)
3578 {
3579  if(s<0 || s>14){return;}
3580  else
3581  {
3582  if(steps<0){steps=0;}
3583  else if(steps>0xFFFF){steps=0xFFFF;}
3584  if(steps != slot[s].mprogress)
3585  {
3586  slot[s].steps = steps;
3587  setFileModified(true,s);
3588  }
3589  }
3590 }
3592 {
3593  if(s<0 || s>14){return 0;}
3594  else{return slot[s].aeris_church;}
3595 }
3596 void FF7Save::setChurchProgress(int s,int progress)
3597 {
3598  if(s<0 || s>14){return;}
3599  else
3600  {
3601  if(progress<0){progress=0;}
3602  if(progress>0xFF){progress=0xFF;}
3603  if(progress != slot[s].aeris_church)
3604  {
3605  slot[s].aeris_church = progress;
3606  setFileModified(true,s);
3607  }
3608  }
3609 }
3610 
3612 {
3613  if(s<0 || s>14){return 0;}
3614  else{return slot[s].donprogress;}
3615 }
3616 void FF7Save::setDonProgress(int s,int progress)
3617 {
3618  if(s<0 || s>14){return;}
3619  else
3620  {
3621  if(progress<0){progress=0;}
3622  if(progress>0xFF){progress=0xFF;}
3623  if(progress != slot[s].donprogress)
3624  {
3625  slot[s].donprogress = progress;
3626  setFileModified(true,s);
3627  }
3628  }
3629 }
3631 {
3632  if(s<0 || s>14){return false;}
3633  else
3634  {
3635  if(slot[s].intbombing == 0x14){return true;}
3636  else{return false;}
3637  }
3638 }
3639 void FF7Save::setStartBombingMission(int s,bool isTrue)
3640 {
3641  if(s<0 || s>14){return;}
3642  else
3643  {
3644 
3645  if(isTrue && slot[s].intbombing !=0x14)
3646  {
3647  slot[s].intbombing = 0x14;
3648  setFileModified(true,s);
3649  }
3650  else
3651  {
3652  if(slot[s].intbombing!=0x56)
3653  {
3654  slot[s].intbombing = 0x56;
3655  setFileModified(true,s);
3656  }
3657  }
3658  }
3659 }
3660 quint32 FF7Save::uWeaponHp(int s)
3661 {
3662  if(s<0 || s>14){return 0;}
3663  else{return (slot[s].u_weapon_hp[0] |(slot[s].u_weapon_hp[1] << 8) | (slot[s].u_weapon_hp[2] << 16));}
3664 }
3665 void FF7Save::setUWeaponHp(int s,int hp)
3666 {
3667  if(s<0 || s>14){return;}
3668  else
3669  {
3670  if(quint32(hp) != uWeaponHp(s))
3671  {
3672  int a = (hp & 0xff);
3673  int b = (hp & 0xff00) >> 8;
3674  int c = (hp & 0xff0000) >> 16;
3675  slot[s].u_weapon_hp[0] = a;
3676  slot[s].u_weapon_hp[1] = b;
3677  slot[s].u_weapon_hp[2] = c;
3678  setFileModified(true,s);
3679  }
3680  }
3681 }
3683 {
3684  if(s<0 || s>14){return false;}
3685  else
3686  {
3687  if((slot[s].ruby_emerald)&(1<<4)){return true;}
3688  else{return false;}
3689  }
3690 }
3691 void FF7Save::setKilledEmeraldWeapon(int s,bool isTrue)
3692 {
3693  if(s<0 ||s>14){return;}
3694  else
3695  {
3696  if(isTrue !=killedEmeraldWeapon(s))
3697  {
3698  if(isTrue){slot[s].ruby_emerald |= (1<<4);}
3699  else{slot[s].ruby_emerald &= ~(1<<4);}
3700  setFileModified(true,s);
3701  }
3702  }
3703 }
3704 
3706 {
3707  if(s<0 || s>14){return false;}
3708  else
3709  {
3710  if((slot[s].ruby_emerald)&(1<<3)){return true;}
3711  else{return false;}
3712  }
3713 }
3714 
3715 void FF7Save::setKilledRubyWeapon(int s,bool isTrue)
3716 {
3717  if(s<0 ||s>14){return;}
3718  else
3719  {
3720  if(isTrue !=killedRubyWeapon(s))
3721  {
3722  if(isTrue){slot[s].ruby_emerald |= (1<<3);}
3723  else{slot[s].ruby_emerald &= ~(1<<3);}
3724  setFileModified(true,s);
3725  }
3726  }
3727 }
3728 quint8 FF7Save::tutSave(int s)
3729 {
3730  if(s<0 || s>14){return 0;}
3731  else{return slot[s].tut_save;}
3732 }
3733 void FF7Save::setTutSave(int s, int value)
3734 {
3735  if(s<0 || s>14){return;}
3736  if(value<0){value =0;}
3737  if(value>0xFF){value =0xFF;}
3738  if(value != slot[s].tut_save)
3739  {
3740  slot[s].tut_save=value;
3741  setFileModified(true,s);
3742  }
3743 }
3745 {
3746  if(s<0 || s>14){return false;}
3747  else{return (slot[s].yuffieforest) & (1<<0);}
3748 }
3749 void FF7Save::setCanFightNinjaInForest(int s,bool isTrue)
3750 {
3751  if(s<0 ||s>14){return;}
3752  else
3753  {
3754  if(isTrue !=canFightNinjaInForest(s))
3755  {
3756  if(isTrue){slot[s].yuffieforest |= (1<<0);}
3757  else{slot[s].yuffieforest &= ~(1<<0);}
3758  setFileModified(true,s);
3759  }
3760  }
3761 }
3762 quint8 FF7Save::tutSub(int s)
3763 {
3764  if(s<0 || s>14){return 0;}
3765  else{return slot[s].tut_sub;}
3766 }
3767 bool FF7Save::tutSub(int s, int bit)
3768 {//the Bit Number to offset.
3769  if(bit <0 || bit> 7){return false;}
3770  else{return ((slot[s].tut_sub)& (1<<bit) );}
3771 }
3772 void FF7Save::setTutSub(int s, int bit, bool isTrue)
3773 {
3774  if(s<0 || s>14){return;}
3775  else if(bit<0 || bit >7){return;}
3776  else if(bit ==6){setBattleTargets(s,isTrue);}
3777  else
3778  {
3779  if(isTrue){slot[s].tut_sub |= (1<<bit);}
3780  else{slot[s].tut_sub &= ~(1<<bit);}
3781  setFileModified(true,s);
3782  }
3783 }
3784 void FF7Save::setTutSub(int s, int value)
3785 {
3786  if(s<0||s>14){return;}
3787  else
3788  {
3789  if(value<0){value=0;}
3790  else if(value>0xFF){value=0xFF;}
3791  if(value != slot[s].tut_sub)
3792  {
3793  slot[s].tut_sub = value;
3794  setFileModified(true,s);
3795  }
3796  }
3797 }
3799 {
3800  if(s<0 || s>14){return false;}
3801  else{return (slot[s].reg_yuffie & (1<<0));}
3802 }
3803 void FF7Save::setYuffieUnlocked(int s,bool isUnlocked)
3804 {
3805  if(s<0 || s>14){return;}
3806  else
3807  {
3808  if(isUnlocked){slot[s].reg_yuffie |= (1<<0);}
3809  else{slot[s].reg_yuffie &= ~(1<<0);}
3810  setFileModified(true,s);
3811  }
3812 }
3813 
3815 {
3816  if(s<0 || s>14){return false;}
3817  else{return (slot[s].reg_vinny&(1<<2));}
3818 }
3819 
3820 void FF7Save::setVincentUnlocked(int s,bool isUnlocked)
3821 {
3822  if(s<0 || s>14){return;}
3823  else
3824  {
3825  if(isUnlocked){slot[s].reg_vinny |= (1<<2);}
3826  else{slot[s].reg_vinny &= ~(1<<2);}
3827  setFileModified(true,s);
3828  }
3829 }
3830 
3831 bool FF7Save::worldChocobo(int s, int bit)
3832 {//the Bit Number to offset.
3833  if(bit <0 || bit> 7){return false;}
3834  else{return ((slot[s].world_map_chocobos)& (1<<bit) );}
3835 }
3836 
3837 void FF7Save::setWorldChocobo(int s, int bit, bool isTrue)
3838 {
3839  if(s<0 || s>14){return;}
3840  else if(bit<0 || bit >7){return;}
3841  else
3842  {
3843  if(isTrue){slot[s].world_map_chocobos |= (1<<bit);}
3844  else{slot[s].world_map_chocobos &= ~(1<<bit);}
3845  setFileModified(true,s);
3846  }
3847 }
3848 
3849 bool FF7Save::worldVehicle(int s, int bit)
3850 {//the Bit Number to offset.
3851  if(bit <0 || bit> 7){return false;}
3852  else{return ((slot[s].world_map_vehicles)& (1<<bit) );}
3853 }
3854 
3855 void FF7Save::setWorldVehicle(int s, int bit, bool isTrue)
3856 {
3857  if(s<0 || s>14){return;}
3858  else if(bit<0 || bit >7){return;}
3859  else
3860  {
3861  if(isTrue){slot[s].world_map_vehicles |= (1<<bit);}
3862  else{slot[s].world_map_vehicles &= ~(1<<bit);}
3863  setFileModified(true,s);
3864  }
3865 }
3866 quint32 FF7Save::worldCoordsLeader(int s, bool firstChunk)
3867 {
3868  if(s<0 || s>14){return 0;}
3869  else
3870  {
3871  if(firstChunk){return slot[s].l_world;}
3872  else{return slot[s].l_world2;}
3873  }
3874 }
3876 {
3877  if(s<0 || s>14){return 0;}
3878  else{return (slot[s].l_world &0x7FFFF);}
3879 }
3881 {
3882  if(s<0 || s>14){return 0;}
3883  else{return ((slot[s].l_world >> 19)&0x1F);}
3884 }
3886 {
3887  if(s<0 || s>14){return 0;}
3888  else{return ((slot[s].l_world) >> 24);}
3889 }
3891 {
3892  if(s<0 || s>14){return 0;}
3893  else{return ((slot[s].l_world2) & 0x3FFFF);}
3894 }
3896 {
3897  if(s<0 || s>14){return 0;}
3898  else{return ((slot[s].l_world2) >> 18);}
3899 }
3900 void FF7Save::setWorldCoordsLeader(int s,bool firstChunk,int value)
3901 {
3902  if(s<0 || s>14){return;}
3903  if(value<0){value =0;}
3904  if(value>0xFFFF){value =0xFFFF;}
3905  if(firstChunk && quint32(value) != worldCoordsLeader(s,true))
3906  {
3907  slot[s].l_world=value;
3908  setFileModified(true,s);
3909  }
3910  else
3911  {
3912  if(quint32(value) != worldCoordsLeader(s,false))
3913  {
3914  slot[s].l_world2=value;
3915  setFileModified(true,s);
3916  }
3917  }
3918 }
3919 void FF7Save::setWorldCoordsLeaderX(int s,int value)
3920 {
3921  if(s<0 || s>14){return;}
3922  if(value<0){value=0;}
3923  if(value>295000){value=295000;}
3924  if(value != worldCoordsLeaderX(s))
3925  {
3926  slot[s].l_world = (value | worldCoordsLeaderID(s) << 19 | worldCoordsLeaderAngle(s) << 24);
3927  setFileModified(true,s);
3928  }
3929 }
3930 void FF7Save::setWorldCoordsLeaderID(int s,int value)
3931 {
3932  if(s<0 || s>14){return;}
3933  if(value<0){value=0;}
3934  if(value>255){value=255;}
3935  if(value != worldCoordsLeaderID(s))
3936  {
3937  slot[s].l_world = (worldCoordsLeaderX(s) | value << 19 | worldCoordsLeaderAngle(s) << 24);
3938  setFileModified(true,s);
3939  }
3940 }
3942 {
3943  if(s<0 || s>14){return;}
3944  if(value<0){value=0;}
3945  if(value>360){value=360;}
3946  if(value != worldCoordsLeaderAngle(s))
3947  {
3948  slot[s].l_world = (worldCoordsLeaderX(s) | worldCoordsLeaderID(s) << 19 | value << 24);
3949  setFileModified(true,s);
3950  }
3951 }
3952 void FF7Save::setWorldCoordsLeaderY(int s,int value)
3953 {
3954  if(s<0 || s>14){return;}
3955  if(value<0){value=0;}
3956  if(value>230000){value=230000;}
3957  if(value != worldCoordsLeaderY(s))
3958  {
3959  slot[s].l_world2 = (value | worldCoordsLeaderZ(s) << 18);
3960  setFileModified(true,s);
3961  }
3962 
3963 }
3964 void FF7Save::setWorldCoordsLeaderZ(int s,int value)
3965 {
3966  if(s<0 || s>14){return;}
3967  if(value<0){value=0;}
3968  if(value>255){value=255;}
3969  if(value != worldCoordsLeaderZ(s))
3970  {
3971  slot[s].l_world2 = (worldCoordsLeaderY(s) | value << 18);
3972  setFileModified(true,s);
3973  }
3974 }
3975 quint32 FF7Save::worldCoordsTc(int s, bool firstChunk)
3976 {
3977  if(s<0 || s>14){return 0;}
3978  else
3979  {
3980  if(firstChunk){return slot[s].tc_world;}
3981  else{return slot[s].tc_world2;}
3982  }
3983 }
3985 {
3986  if(s<0 || s>14){return 0;}
3987  else{return (slot[s].tc_world &0x7FFFF);}
3988 }
3990 {
3991  if(s<0 || s>14){return 0;}
3992  else{return ((slot[s].tc_world >> 19)&0x1F);}
3993 }
3995 {
3996  if(s<0 || s>14){return 0;}
3997  else{return ((slot[s].tc_world) >> 24);}
3998 }
4000 {
4001  if(s<0 || s>14){return 0;}
4002  else{return ((slot[s].tc_world2) & 0x3FFFF);}
4003 }
4005 {
4006  if(s<0 || s>14){return 0;}
4007  else{return ((slot[s].tc_world2) >> 18);}
4008 }
4009 void FF7Save::setWorldCoordsTc(int s,bool firstChunk,int value)
4010 {
4011  if(s<0 || s>14){return;}
4012  if(value<0){value =0;}
4013  if(value>0xFFFF){value =0xFFFF;}
4014  if(firstChunk && quint32(value) != worldCoordsTc(s,true))
4015  {
4016  slot[s].tc_world=value;
4017  setFileModified(true,s);
4018  }
4019  else
4020  {
4021  if(quint32(value) != worldCoordsTc(s,false))
4022  {
4023  slot[s].tc_world2=value;
4024  setFileModified(true,s);
4025  }
4026  }
4027 }
4028 void FF7Save::setWorldCoordsTcX(int s,int value)
4029 {
4030  if(s<0 || s>14){return;}
4031  if(value<0){value=0;}
4032  if(value>295000){value=295000;}
4033  if(value != worldCoordsTcX(s))
4034  {
4035  slot[s].tc_world = (value | worldCoordsTcID(s) << 19 | worldCoordsTcAngle(s) << 24);
4036  setFileModified(true,s);
4037  }
4038 }
4039 void FF7Save::setWorldCoordsTcID(int s,int value)
4040 {
4041  if(s<0 || s>14){return;}
4042  if(value<0){value=0;}
4043  if(value>255){value=255;}
4044  if(value != worldCoordsTcID(s))
4045  {
4046  slot[s].tc_world = (worldCoordsTcX(s) | value << 19 | worldCoordsTcAngle(s) << 24);
4047  setFileModified(true,s);
4048  }
4049 }
4050 void FF7Save::setWorldCoordsTcAngle(int s,int value)
4051 {
4052  if(s<0 || s>14){return;}
4053  if(value<0){value=0;}
4054  if(value>360){value=360;}
4055  if(value != worldCoordsTcAngle(s))
4056  {
4057  slot[s].tc_world = (worldCoordsTcX(s) | worldCoordsTcID(s) << 19 | value << 24);
4058  setFileModified(true,s);
4059  }
4060 }
4061 void FF7Save::setWorldCoordsTcY(int s,int value)
4062 {
4063  if(s<0 || s>14){return;}
4064  if(value<0){value=0;}
4065  if(value>230000){value=230000;}
4066  if(value != worldCoordsTcY(s))
4067  {
4068  slot[s].tc_world2 = (value | worldCoordsTcZ(s) << 18);
4069  setFileModified(true,s);
4070  }
4071 
4072 }
4073 void FF7Save::setWorldCoordsTcZ(int s,int value)
4074 {
4075  if(s<0 || s>14){return;}
4076  if(value<0){value=0;}
4077  if(value>255){value=255;}
4078  if(value != worldCoordsTcZ(s))
4079  {
4080  slot[s].tc_world2 = (worldCoordsTcY(s) | value << 18);
4081  setFileModified(true,s);
4082  }
4083 }
4084 quint32 FF7Save::worldCoordsBh(int s, bool firstChunk)
4085 {
4086  if(s<0 || s>14){return 0;}
4087  else
4088  {
4089  if(firstChunk){return slot[s].bh_world;}
4090  else{return slot[s].bh_world2;}
4091  }
4092 }
4094 {
4095  if(s<0 || s>14){return 0;}
4096  else{return (slot[s].bh_world &0x7FFFF);}
4097 }
4099 {
4100  if(s<0 || s>14){return 0;}
4101  else{return ((slot[s].bh_world >> 19)&0x1F);}
4102 }
4104 {
4105  if(s<0 || s>14){return 0;}
4106  else{return ((slot[s].bh_world) >> 24);}
4107 }
4109 {
4110  if(s<0 || s>14){return 0;}
4111  else{return ((slot[s].bh_world2) & 0x3FFFF);}
4112 }
4114 {
4115  if(s<0 || s>14){return 0;}
4116  else{return ((slot[s].bh_world2) >> 18);}
4117 }
4118 void FF7Save::setWorldCoordsBh(int s,bool firstChunk,int value)
4119 {
4120  if(s<0 || s>14){return;}
4121  if(value<0){value =0;}
4122  if(value>0xFFFF){value =0xFFFF;}
4123  if(firstChunk && quint32(value) != worldCoordsBh(s,true))
4124  {
4125  slot[s].bh_world=value;
4126  setFileModified(true,s);
4127  }
4128  else
4129  {
4130  if(quint32(value) != worldCoordsBh(s,false))
4131  {
4132  slot[s].bh_world2=value;
4133  setFileModified(true,s);
4134  }
4135  }
4136 }
4137 void FF7Save::setWorldCoordsBhX(int s,int value)
4138 {
4139  if(s<0 || s>14){return;}
4140  if(value<0){value=0;}
4141  if(value>295000){value=295000;}
4142  if(value != worldCoordsBhX(s))
4143  {
4144  slot[s].bh_world = (value | worldCoordsBhID(s) << 19 | worldCoordsBhAngle(s) << 24);
4145  setFileModified(true,s);
4146  }
4147 }
4148 void FF7Save::setWorldCoordsBhID(int s,int value)
4149 {
4150  if(s<0 || s>14){return;}
4151  if(value<0){value=0;}
4152  if(value>255){value=255;}
4153  if(value != worldCoordsBhID(s))
4154  {
4155  slot[s].bh_world = (worldCoordsBhX(s) | value << 19 | worldCoordsBhAngle(s) << 24);
4156  setFileModified(true,s);
4157  }
4158 }
4159 void FF7Save::setWorldCoordsBhAngle(int s,int value)
4160 {
4161  if(s<0 || s>14){return;}
4162  if(value<0){value=0;}
4163  if(value>360){value=360;}
4164  if(value != worldCoordsBhAngle(s))
4165  {
4166  slot[s].bh_world = (worldCoordsBhX(s) | worldCoordsBhID(s) << 19 | value << 24);
4167  setFileModified(true,s);
4168  }
4169 }
4170 void FF7Save::setWorldCoordsBhY(int s,int value)
4171 {
4172  if(s<0 || s>14){return;}
4173  if(value<0){value=0;}
4174  if(value>230000){value=230000;}
4175  if(value != worldCoordsBhY(s))
4176  {
4177  slot[s].bh_world2 = (value | worldCoordsBhZ(s) << 18);
4178  setFileModified(true,s);
4179  }
4180 
4181 }
4182 void FF7Save::setWorldCoordsBhZ(int s,int value)
4183 {
4184  if(s<0 || s>14){return;}
4185  if(value<0){value=0;}
4186  if(value>255){value=255;}
4187  if(value != worldCoordsBhZ(s))
4188  {
4189  slot[s].bh_world2 = (worldCoordsBhY(s) | value << 18);
4190  setFileModified(true,s);
4191  }
4192 }
4193 
4194 quint32 FF7Save::worldCoordsSub(int s, bool firstChunk)
4195 {
4196  if(s<0 || s>14){return 0;}
4197  else
4198  {
4199  if(firstChunk){return slot[s].sub_world;}
4200  else{return slot[s].sub_world2;}
4201  }
4202 }
4204 {
4205  if(s<0 || s>14){return 0;}
4206  else{return (slot[s].sub_world &0x7FFFF);}
4207 }
4209 {
4210  if(s<0 || s>14){return 0;}
4211  else{return ((slot[s].sub_world >> 19)&0x1F);}
4212 }
4214 {
4215  if(s<0 || s>14){return 0;}
4216  else{return ((slot[s].sub_world) >> 24);}
4217 }
4219 {
4220  if(s<0 || s>14){return 0;}
4221  else{return ((slot[s].sub_world2) & 0x3FFFF);}
4222 }
4224 {
4225  if(s<0 || s>14){return 0;}
4226  else{return ((slot[s].sub_world2) >> 18);}
4227 }
4228 void FF7Save::setWorldCoordsSub(int s,bool firstChunk,int value)
4229 {
4230  if(s<0 || s>14){return;}
4231  if(value<0){value =0;}
4232  if(value>0xFFFF){value =0xFFFF;}
4233  if(firstChunk && quint32(value) != worldCoordsSub(s,true))
4234  {
4235  slot[s].sub_world=value;
4236  setFileModified(true,s);
4237  }
4238  else
4239  {
4240  if(quint32(value) != worldCoordsSub(s,false))
4241  {
4242  slot[s].sub_world2=value;
4243  setFileModified(true,s);
4244  }
4245  }
4246 }
4247 void FF7Save::setWorldCoordsSubX(int s,int value)
4248 {
4249  if(s<0 || s>14){return;}
4250  if(value<0){value=0;}
4251  if(value>295000){value=295000;}
4252  if(value != worldCoordsSubX(s))
4253  {
4254  slot[s].sub_world = (value | worldCoordsSubID(s) << 19 | worldCoordsSubAngle(s) << 24);
4255  setFileModified(true,s);
4256  }
4257 }
4258 void FF7Save::setWorldCoordsSubID(int s,int value)
4259 {
4260  if(s<0 || s>14){return;}
4261  if(value<0){value=0;}
4262  if(value>255){value=255;}
4263  if(value != worldCoordsSubID(s))
4264  {
4265  slot[s].sub_world = (worldCoordsSubX(s) | value << 19 | worldCoordsSubAngle(s) << 24);
4266  setFileModified(true,s);
4267  }
4268 }
4269 void FF7Save::setWorldCoordsSubAngle(int s,int value)
4270 {
4271  if(s<0 || s>14){return;}
4272  if(value<0){value=0;}
4273  if(value>360){value=360;}
4274  if(value != worldCoordsSubAngle(s))
4275  {
4276  slot[s].sub_world = (worldCoordsSubX(s) | worldCoordsSubID(s) << 19 | value << 24);
4277  setFileModified(true,s);
4278  }
4279 }
4280 void FF7Save::setWorldCoordsSubY(int s,int value)
4281 {
4282  if(s<0 || s>14){return;}
4283  if(value<0){value=0;}
4284  if(value>230000){value=230000;}
4285  if(value != worldCoordsSubY(s))
4286  {
4287  slot[s].sub_world2 = (value | worldCoordsSubZ(s) << 18);
4288  setFileModified(true,s);
4289  }
4290 
4291 }
4292 void FF7Save::setWorldCoordsSubZ(int s,int value)
4293 {
4294  if(s<0 || s>14){return;}
4295  if(value<0){value=0;}
4296  if(value>255){value=255;}
4297  if(value != worldCoordsSubZ(s))
4298  {
4299  slot[s].sub_world2 = (worldCoordsSubY(s) | value << 18);
4300  setFileModified(true,s);
4301  }
4302 }
4303 
4304 quint32 FF7Save::worldCoordsWchoco(int s, bool firstChunk)
4305 {
4306  if(s<0 || s>14){return 0;}
4307  else
4308  {
4309  if(firstChunk){return slot[s].wc_world;}
4310  else{return slot[s].wc_world2;}
4311  }
4312 }
4314 {
4315  if(s<0 || s>14){return 0;}
4316  else{return (slot[s].wc_world &0x7FFFF);}
4317 }
4319 {
4320  if(s<0 || s>14){return 0;}
4321  else{return ((slot[s].wc_world >> 19)&0x1F);}
4322 }
4324 {
4325  if(s<0 || s>14){return 0;}
4326  else{return ((slot[s].wc_world) >> 24);}
4327 }
4329 {
4330  if(s<0 || s>14){return 0;}
4331  else{return ((slot[s].wc_world2) & 0x3FFFF);}
4332 }
4334 {
4335  if(s<0 || s>14){return 0;}
4336  else{return ((slot[s].wc_world2) >> 18);}
4337 }
4338 void FF7Save::setWorldCoordsWchoco(int s,bool firstChunk,int value)
4339 {
4340  if(s<0 || s>14){return;}
4341  if(value<0){value =0;}
4342  if(value>0xFFFF){value =0xFFFF;}
4343  if(firstChunk && quint32(value) != worldCoordsWchoco(s,true))
4344  {
4345  slot[s].wc_world=value;
4346  setFileModified(true,s);
4347  }
4348  else
4349  {
4350  if(quint32(value) != worldCoordsWchoco(s,false))
4351  {
4352  slot[s].wc_world2=value;
4353  setFileModified(true,s);
4354  }
4355  }
4356 }
4357 void FF7Save::setWorldCoordsWchocoX(int s,int value)
4358 {
4359  if(s<0 || s>14){return;}
4360  if(value<0){value=0;}
4361  if(value>295000){value=295000;}
4362  if(value != worldCoordsWchocoX(s))
4363  {
4364  slot[s].wc_world = (value | worldCoordsWchocoID(s) << 19 | worldCoordsWchocoAngle(s) << 24);
4365  setFileModified(true,s);
4366  }
4367 }
4368 void FF7Save::setWorldCoordsWchocoID(int s,int value)
4369 {
4370  if(s<0 || s>14){return;}
4371  if(value<0){value=0;}
4372  if(value>255){value=255;}
4373  if(value != worldCoordsWchocoID(s))
4374  {
4375  slot[s].wc_world = (worldCoordsWchocoX(s) | value << 19 | worldCoordsWchocoAngle(s) << 24);
4376  setFileModified(true,s);
4377  }
4378 }
4380 {
4381  if(s<0 || s>14){return;}
4382  if(value<0){value=0;}
4383  if(value>360){value=360;}
4384  if(value != worldCoordsWchocoAngle(s))
4385  {
4386  slot[s].wc_world = (worldCoordsWchocoX(s) | worldCoordsWchocoID(s) << 19 | value << 24);
4387  setFileModified(true,s);
4388  }
4389 }
4390 void FF7Save::setWorldCoordsWchocoY(int s,int value)
4391 {
4392  if(s<0 || s>14){return;}
4393  if(value<0){value=0;}
4394  if(value>230000){value=230000;}
4395  if(value != worldCoordsWchocoY(s))
4396  {
4397  slot[s].wc_world2 = (value | worldCoordsWchocoZ(s) << 18);
4398  setFileModified(true,s);
4399  }
4400 
4401 }
4402 void FF7Save::setWorldCoordsWchocoZ(int s,int value)
4403 {
4404  if(s<0 || s>14){return;}
4405  if(value<0){value=0;}
4406  if(value>255){value=255;}
4407  if(value != worldCoordsWchocoZ(s))
4408  {
4409  slot[s].wc_world2 = (worldCoordsWchocoY(s) | value << 18);
4410  setFileModified(true,s);
4411  }
4412 }
4413 
4414 
4415 quint32 FF7Save::worldCoordsDurw(int s, bool firstChunk)
4416 {
4417  if(s<0 || s>14){return 0;}
4418  else
4419  {
4420  if(firstChunk){return slot[s].durw_world;}
4421  else{return slot[s].durw_world2;}
4422  }
4423 }
4425 {
4426  if(s<0 || s>14){return 0;}
4427  else{return (slot[s].durw_world &0x7FFFF);}
4428 }
4430 {
4431  if(s<0 || s>14){return 0;}
4432  else{return ((slot[s].durw_world >> 19)&0x1F);}
4433 }
4435 {
4436  if(s<0 || s>14){return 0;}
4437  else{return ((slot[s].durw_world) >> 24);}
4438 }
4440 {
4441  if(s<0 || s>14){return 0;}
4442  else{return ((slot[s].durw_world2) & 0x3FFFF);}
4443 }
4445 {
4446  if(s<0 || s>14){return 0;}
4447  else{return ((slot[s].durw_world2) >> 18);}
4448 }
4449 void FF7Save::setWorldCoordsDurw(int s,bool firstChunk,int value)
4450 {
4451  if(s<0 || s>14){return;}
4452  if(value<0){value =0;}
4453  if(value>0xFFFF){value =0xFFFF;}
4454  if(firstChunk && quint32(value) != worldCoordsDurw(s,true))
4455  {
4456  slot[s].durw_world=value;
4457  setFileModified(true,s);
4458  }
4459  else
4460  {
4461  if(quint32(value) != worldCoordsDurw(s,false))
4462  {
4463  slot[s].durw_world2=value;
4464  setFileModified(true,s);
4465  }
4466  }
4467 }
4468 void FF7Save::setWorldCoordsDurwX(int s,int value)
4469 {
4470  if(s<0 || s>14){return;}
4471  if(value<0){value=0;}
4472  if(value>295000){value=295000;}
4473  if(value != worldCoordsDurwX(s))
4474  {
4475  slot[s].durw_world = (value | worldCoordsDurwID(s) << 19 | worldCoordsDurwAngle(s) << 24);
4476  setFileModified(true,s);
4477  }
4478 }
4479 void FF7Save::setWorldCoordsDurwID(int s,int value)
4480 {
4481  if(s<0 || s>14){return;}
4482  if(value<0){value=0;}
4483  if(value>255){value=255;}
4484  if(value != worldCoordsDurwID(s))
4485  {
4486  slot[s].durw_world = (worldCoordsDurwX(s) | value << 19 | worldCoordsDurwAngle(s) << 24);
4487  setFileModified(true,s);
4488  }
4489 }
4491 {
4492  if(s<0 || s>14){return;}
4493  if(value<0){value=0;}
4494  if(value>360){value=360;}
4495  if(value != worldCoordsDurwAngle(s))
4496  {
4497  slot[s].durw_world = (worldCoordsDurwX(s) | worldCoordsDurwID(s) << 19 | value << 24);
4498  setFileModified(true,s);
4499  }
4500 }
4501 void FF7Save::setWorldCoordsDurwY(int s,int value)
4502 {
4503  if(s<0 || s>14){return;}
4504  if(value<0){value=0;}
4505  if(value>230000){value=230000;}
4506  if(value != worldCoordsDurwY(s))
4507  {
4508  slot[s].durw_world2 = (value | worldCoordsDurwZ(s) << 18);
4509  setFileModified(true,s);
4510  }
4511 
4512 }
4513 void FF7Save::setWorldCoordsDurwZ(int s,int value)
4514 {
4515  if(s<0 || s>14){return;}
4516  if(value<0){value=0;}
4517  if(value>255){value=255;}
4518  if(value != worldCoordsDurwZ(s))
4519  {
4520  slot[s].durw_world2 = (worldCoordsDurwY(s) | value << 18);
4521  setFileModified(true,s);
4522  }
4523 }
4525 {
4526  if(s<0 || s>14){return 0;}
4527  else
4528  {
4529  return slot[s].cratersaveMapId;
4530  }
4531 }
4532 void FF7Save::setCraterSavePointMapID(int s, int value)
4533 {
4534  if(s<0 || s>14){return;}
4535  else if(value<0 || value>999){return;}
4536  else
4537  {
4538  slot[s].cratersaveMapId=value;
4539  setFileModified(true,s);
4540  }
4541 }
4543 {
4544  if(s<0 || s>14){return 0;}
4545  else
4546  {
4547  return slot[s].cratersaveX;
4548  }
4549 }
4550 void FF7Save::setCraterSavePointX(int s,int value)
4551 {
4552  if(s<0 || s>14){return;}
4553  else if(value<-32767 || value > 32767){return;}
4554  else
4555  {
4556  slot[s].cratersaveX=value;
4557  setFileModified(true,s);
4558  }
4559 }
4560 
4562 {
4563  if(s<0 || s>14){return 0;}
4564  else
4565  {
4566  return slot[s].cratersaveY;
4567  }
4568 }
4569 void FF7Save::setCraterSavePointY(int s,int value)
4570 {
4571  if(s<0 || s>14){return;}
4572  else if(value<-32767 || value > 32767){return;}
4573  else
4574  {
4575  slot[s].cratersaveY=value;
4576  setFileModified(true,s);
4577  }
4578 }
4580 {
4581  if(s<0 || s>14){return 0;}
4582  else
4583  {
4584  return slot[s].cratersaveZ;
4585  }
4586 }
4587 void FF7Save::setCraterSavePointZ(int s,int value)
4588 {
4589  if(s<0 || s>14){return;}
4590  else if(value<-32767 || value > 32767){return;}
4591  else
4592  {
4593  slot[s].cratersaveZ=value;
4594  setFileModified(true,s);
4595  }
4596 }
4598 {//used when saving a VMC file to adjust slot to save game#
4599  //compare our list to known ff7 region codes to find out what slot we should be writing to
4600  //use strings for each region incase the card contains more then one FF7 regions save.
4601  QStringList us = QStringList()<<QString("FF7-S01")<<QString("FF7-S02")<<QString("FF7-S03")<<QString("FF7-S04")<<QString("FF7-S05")<<QString("FF7-S06")<<QString("FF7-S07")<<QString("FF7-S08")<<QString("FF7-S09")<<QString("FF7-S10")<<QString("FF7-S11")<<QString("FF7-S12")<<QString("FF7-S13")<<QString("FF7-S14")<<QString("FF7-S15");
4602  QStringList uk = us;
4603  QStringList fr = us;
4604  QStringList ge = us;
4605  QStringList es = us;
4606  QStringList jp = us;
4607  QStringList in = us;
4608  for (int i=0;i<s;i++)
4609  {
4610  if(region(i).contains("BASCUS-94163"))
4611  {
4612  us.replace(region(i).mid(17,2).toInt()-1,QString(""));
4613  }
4614  else if(region(i).contains("BESCES-00867"))
4615  {
4616  uk.replace(region(i).mid(17,2).toInt()-1,QString(""));
4617  }
4618  else if(region(i).contains("BESCES-00868"))
4619  {
4620  fr.removeAt(region(i).mid(17,2).toInt()-1);
4621  }
4622  else if(region(i).contains("BESCES-00869"))
4623  {
4624  ge.removeAt(region(i).mid(17,2).toInt()-1);
4625  }
4626  else if(region(i).contains("BESCES-00900"))
4627  {
4628  es.removeAt(region(i).mid(17,2).toInt()-1);
4629  }
4630  else if(region(i).contains("BISLPS-00700"))
4631  {
4632  jp.removeAt(region(i).mid(17,2).toInt()-1);
4633  }
4634  else if(region(i).contains("BISLPS-01057"))
4635  {
4636  in.removeAt(region(i).mid(17,2).toInt()-1);
4637  }
4638  }
4639  QString newRegionString = region(s).mid(0,12);
4640  if(region(s).contains("BASCUS-94163"))
4641  {
4642  for(int i=0;i<15;i++)
4643  {
4644  if(us.at(i) == QString("")){continue;}
4645  else{newRegionString.append(us.at(i));break;}
4646  }
4647  }
4648  else if(region(s).contains("BESCES-00867"))
4649  {
4650  for(int i=0;i<15;i++)
4651  {
4652  if(uk.at(i).isEmpty()){continue;}
4653  else{newRegionString.append(uk.at(i));break;}
4654  }
4655  }
4656  else if(region(s).contains("BESCES-00868"))
4657  {
4658  for(int i=0;i<15;i++)
4659  {
4660  if(fr.at(i).isEmpty()){continue;}
4661  else{newRegionString.append(fr.at(i));break;}
4662  }
4663  }
4664  else if(region(s).contains("BESCES-00869"))
4665  {
4666  for(int i=0;i<15;i++)
4667  {
4668  if(ge.at(i).isEmpty()){continue;}
4669  else{newRegionString.append(ge.at(i));break;}
4670  }
4671  }
4672  else if(region(s).contains("BESCES-00900"))
4673  {
4674  for(int i=0;i<15;i++)
4675  {
4676  if(es.at(i).isEmpty()){continue;}
4677  else{newRegionString.append(es.at(i));break;}
4678  }
4679  }
4680  else if(region(s).contains("BISLPS-00700"))
4681  {
4682  for(int i=0;i<15;i++)
4683  {
4684  if(jp.at(i).isEmpty()){continue;}
4685  else{newRegionString.append(jp.at(i));break;}
4686  }
4687  }
4688  else if(region(s).contains("BISLPS-01057"))
4689  {
4690  for(int i=0;i<15;i++)
4691  {
4692  if(in.at(i).isEmpty()){continue;}
4693  else{newRegionString.append(in.at(i));break;}
4694  }
4695  }
4696  SG_Region_String[s]=newRegionString;
4697 }
4699 {//0x0F38 in game saved as int 1 or int 0
4700  if(s<0 || s>14){return false;}
4701 
4702  if(slot[s].wonsubgame == 1){return true;}
4703  else{return false;}
4704 }
4705 void FF7Save::setSubMiniGameVictory(int s, bool won)
4706 {
4707  if(s<0 || s>14){return;}
4708  int temp = slot[s].wonsubgame;
4709  if(won){slot[s].wonsubgame = 1; }
4710  else{slot[s].wonsubgame = 0;}
4711  if(temp != slot[s].wonsubgame){setFileModified(true,s);}
4712 }
4713 quint8 FF7Save::chocoboRating(int s,int stable)
4714 {
4715  if(s<0 || s>14){return 0;}
4716  else
4717  {
4718  return slot[s].stablechocorating[stable];
4719  }
4720 }
4721 void FF7Save::setChocoboRating(int s,int stable,int rating)
4722 {
4723  if(s<0 || s>14 || stable <0 || stable >5 || rating <0 || rating >8){return;}
4724  else if(rating == slot[s].stablechocorating[stable]){return;}
4725  else
4726  {
4727  slot[s].stablechocorating[stable] = rating;
4728  setFileModified(true,s);
4729  }
4730 }
4731 QList<quint8> FF7Save::chocoboRatings(int s)
4732 {
4733  QList<quint8>ratings;
4734  if(s<0 || s>14){for(int i=0;i<6;i++){ratings.append(0);};}
4735  else
4736  {
4737  for(int i=0;i<6;i++){ratings.append(slot[s].stablechocorating[i]);}
4738  }
4739  return ratings;
4740 }
static const QByteArray MC_SAVE_GAME_FILE_ID
quint8 locationD(int s)
direction player is facing on field map
Definition: FF7Save.cpp:3408
void setCharBaseMp(int s, int char_num, quint16 baseMp)
Definition: FF7Save.cpp:2016
int worldCoordsLeaderY(int s)
Definition: FF7Save.cpp:3890
static const int FF7_MC_SAVE_GAME_FOOTER
int SG_SLOT_HEADER
Definition: FF7Save.h:1023
qint32 charMateriaAp(int s, int who, int mat_num)
Definition: FF7Save.cpp:2046
quint16 itemDecode(quint16 itemraw)
Definition: FF7Save.cpp:658
quint8 chocoPCount(int s, int chocoSlot)
Definition: FF7Save.cpp:2137
void setWorldCoordsBhX(int s, int value)
Definition: FF7Save.cpp:4137
static const int FF7_VGS_SAVE_GAME_SIZE
qint8 stablesOccupied(int s)
Definition: FF7Save.cpp:3501
QByteArray ps3Seed(void)
Definition: FF7Save.h:986
bool isNTSC(int s)
Definition: FF7Save.cpp:1310
static const quint8 PSX_SAVE_GAME_FILE_HEADER_S06[0x100]
QByteArray rawCharacterData(int s, int char_num)
Definition: FF7Save.cpp:1932
void setMessageSpeed(int s, int speed)
Definition: FF7Save.cpp:3122
quint8 charFlag(int s, int char_num, int flag_num)
Definition: FF7Save.cpp:1957
QList< QByteArray > slotIcon(int s)
return slots save icon. each new frame will be appended to the list.
Definition: FF7Save.cpp:1578
quint16 charBaseMp(int s, int char_num)
Definition: FF7Save.cpp:1975
void setSpeedScore(int s, int rank, quint16 score)
Definition: FF7Save.cpp:1812
QList< qint8 > chocoboPens(int s)
return the chocobos in the pen outside of the chocobo farm
Definition: FF7Save.cpp:3525
void setCharMaxHp(int s, int char_num, quint16 maxHp)
Definition: FF7Save.cpp:2018
void setWorldCoordsBhY(int s, int value)
Definition: FF7Save.cpp:4170
quint8 charWeapon(int s, int char_num)
Definition: FF7Save.cpp:1954
static const quint8 PSX_SAVE_GAME_FILE_HEADER_S10[0x100]
QByteArray slotFooter(int s)
Footer for a slot as QByteArray.
Definition: FF7Save.cpp:177
void setWorldCoordsTcID(int s, int value)
Definition: FF7Save.cpp:4039
quint8 itemQty(int s, int item_num)
Definition: FF7Save.cpp:802
QString fileName(void)
Definition: FF7Save.cpp:2496
static const int FF7_DEX_SAVE_GAME_DATA_SIZE
int SG_SIZE
Definition: FF7Save.h:1019
quint8 chocoIntelligence(int s, int chocoSlot)
Definition: FF7Save.cpp:2123
void setVincentUnlocked(int s, bool isUnlocked)
set if vincent has been unlocked
Definition: FF7Save.cpp:3820
bool exportVGS(const QString &fileName)
attempt to save fileName as a Virtual Game Station format memory card file
Definition: FF7Save.cpp:403
void setPsx_block_next(int s, int next)
Definition: FF7Save.cpp:1185
quint8 tutSub(int s)
Definition: FF7Save.cpp:3762
void setCharSpi(int s, int char_num, quint8 spi)
Definition: FF7Save.cpp:1987
void setCraterSavePointMapID(int s, int value)
set the map that the placeable save point is on
Definition: FF7Save.cpp:4532
void setCharCurrentHp(int s, int char_num, quint16 curHp)
Definition: FF7Save.cpp:2013
void setCraterSavePointZ(int s, int value)
set z coordinate of the placeable save point
Definition: FF7Save.cpp:4587
int worldCoordsDurwX(int s)
Definition: FF7Save.cpp:4424
quint8 stolenMateriaId(int s, int mat_num)
Definition: FF7Save.cpp:1888
static const int FF7_MC_SAVE_GAME_DATA_SIZE
void setLocationId(int s, quint16 locationID)
set location id save is located on
Definition: FF7Save.cpp:3334
quint16 charMaxMp(int s, int char_num)
Definition: FF7Save.cpp:1978
int battleSpeed(int s)
Definition: FF7Save.cpp:3110
bool setSlotPsxRawData(int s, QByteArray data)
set the slots raw psx data
Definition: FF7Save.cpp:218
static const QByteArray PSX_SAVE_GAME_FILE_ID
Definition: FF7Save_Const.h:43
void setCharDexBonus(int s, int char_num, quint8 dexbonus)
Definition: FF7Save.cpp:1994
void setPhsAllowed(int s, int who, bool checked)
Definition: FF7Save.cpp:3245
a chocobo in save game
void setCharLck(int s, int char_num, quint8 lck)
Definition: FF7Save.cpp:1989
void importSlot(int s=0, QString fileName="", int fileSlot=0)
import from a file into a slot
Definition: FF7Save.cpp:485
static const QByteArray PSV_SAVE_GAME_FILE_ID
quint32 countdownTimer(int s)
Definition: FF7Save.cpp:3542
int SG_SLOT_NUMBER
Definition: FF7Save.h:1026
void setDialogColorUL(int s, QColor color)
Definition: FF7Save.cpp:1900
void setWorldCoordsDurwAngle(int s, int value)
Definition: FF7Save.cpp:4490
static const quint8 PSX_SAVE_GAME_FILE_HEADER_S07[0x100]
QByteArray slotPsxRawData(int s)
QByteArray of a psx save (multiblock saves are ok)
Definition: FF7Save.cpp:191
void setWorldCoordsWchocoY(int s, int value)
Definition: FF7Save.cpp:4390
bool setKeyItems(int s, QByteArray data)
Definition: FF7Save.cpp:2737
int worldCoordsSubID(int s)
Definition: FF7Save.cpp:4208
bool isFileModified(void)
Definition: FF7Save.cpp:1285