Advertisement
NightFox

Savegame example from Spirits DS

Sep 11th, 2012
201
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.80 KB | None | 0 0
  1. /*
  2. -------------------------------------------------
  3.  
  4.     Spirits DS
  5.  
  6.     Archivo de funciones de guardado de datos
  7.  
  8.     Requiere DevkitARM
  9.     Requiere NightFox's Lib
  10.  
  11.     Codigo por NightFox
  12.     http://www.nightfoxandco.com
  13.     Inicio 02 de Septiembre del 2011
  14.  
  15.     (c)2008 - 2012 NightFox & Co.
  16.  
  17. -------------------------------------------------
  18. */
  19.  
  20.  
  21.  
  22. // Includes C
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include <unistd.h>
  26.  
  27. // Includes propietarios NDS
  28. #include <nds.h>
  29.  
  30. // Includes NightFox's Lib
  31. #include <nf_lib.h>
  32.  
  33. //Incluye las librerias del juego
  34. #include "includes.h"
  35.  
  36.  
  37.  
  38. // Funcion CheckSavegame();
  39. void CheckSavegame(const char* path) {
  40.  
  41.     // Verifica si es un emulador o el hardware real
  42.     if (CheckFATWrite(path)) {
  43.         // Operaciones en el hardware real
  44.         sprintf(SAVEFILEPATH, path);
  45.         IS_EMULATOR = false;
  46.         CheckSavegameFile();
  47.     } else {
  48.         // Operaciones en el emulador
  49.         IS_EMULATOR = true;
  50.         CheckSavegameSRAM();
  51.     }
  52.  
  53. }
  54.  
  55.  
  56. // Funcion WriteSavegame();
  57. void WriteSavegame(void) {
  58.  
  59.     // Guardalos donde tocan
  60.     if (IS_EMULATOR) {
  61.         if (USE_SRAM && !REG_DSIMODE) WriteSRAM();
  62.     } else {
  63.         WriteSavegameFile();
  64.     }
  65.  
  66. }
  67.  
  68.  
  69.  
  70. // Funcion ReadSavegame();
  71. void ReadSavegame(void) {
  72.  
  73.     // Guardalos donde tocan
  74.     if (IS_EMULATOR) {
  75.         if (USE_SRAM && !REG_DSIMODE) ReadSRAM();
  76.     } else {
  77.         ReadSavegameFile();
  78.     }
  79.  
  80. }
  81.  
  82.  
  83.  
  84.  
  85. // Funcion CheckSavegameFile();
  86. void CheckSavegameFile(void) {
  87.  
  88.     // Variables
  89.     bool filefound = false;     // Existe el fichero
  90.     u16 l = 0;                  // Longitud del path al archivo
  91.     FILE* savefile;             // Puntero de archivo
  92.     u32 checksum = 0;           // Checksum del savedata
  93.  
  94.     // Añade la extension .SAV al archivo de guardado
  95.     l = strlen(SAVEFILEPATH);
  96.     SAVEFILEPATH[(l - 3)] = 's';
  97.     SAVEFILEPATH[(l - 2)] = 'a';
  98.     SAVEFILEPATH[(l - 1)] = 'v';
  99.  
  100.     // Verifica si existe el archivo de guardado
  101.     savefile = fopen(SAVEFILEPATH, "rb");
  102.     if (savefile) {
  103.         filefound = true;
  104.     } else {
  105.         filefound = false;
  106.     }
  107.     fclose(savefile);
  108.  
  109.     // Si el archivo de guardado existe...
  110.     if (filefound) {
  111.         // Lee el archivo
  112.         ReadSavegameFile();
  113.         // Realiza el checksum de los datos cargados
  114.         checksum = SavedataChecksum();
  115.         // Verifica si hay discrepancias
  116.         if (
  117.             (checksum != CHECKSUM[0].value)
  118.             ||
  119.             (CHECKSUM[0].version != SAVEGAMEVERSION)
  120.             ||
  121.             (strcmp(CHECKSUM[0].magic, "SPIRITSDS") != 0)
  122.             ) {
  123.             // Si las hay, inicializa los datos del juego
  124.             InitGameData();
  125.             // Graba el archivo
  126.             WriteSavegameFile();
  127.         }
  128.     } else {    // Si no existe, crea los datos de guardado y crealo
  129.         // Inicializa los datos del juego
  130.         InitGameData();
  131.         // Graba el archivo
  132.         WriteSavegameFile();
  133.     }
  134.  
  135. }
  136.  
  137.  
  138.  
  139. // Funcion WriteSavegameFile();
  140. void WriteSavegameFile(void) {
  141.  
  142.     // Variables
  143.     FILE* savefile;             // Puntero de archivo
  144.  
  145.     // Alamacena el CHECKSUM
  146.     CHECKSUM[0].value = SavedataChecksum();
  147.  
  148.     // Crea el Archivo
  149.     savefile = fopen(SAVEFILEPATH, "wb");
  150.  
  151.     // Graba los datos solo en caso de poder escribir el archivo
  152.     if (savefile) {
  153.         fwrite((void*)&CHECKSUM, sizeof(CHECKSUM), 1, savefile);
  154.         fwrite((void*)&GAMEOPTIONS, sizeof(GAMEOPTIONS), 1, savefile);
  155.     }
  156.  
  157.     // Cierra el archivo
  158.     fclose(savefile);
  159.  
  160. }
  161.  
  162.  
  163.  
  164. // Funcion ReadSavegameFile();
  165. void ReadSavegameFile(void) {
  166.  
  167.     // Variables
  168.     FILE* savefile;             // Puntero de archivo
  169.  
  170.     // Abre el Archivo
  171.     savefile = fopen(SAVEFILEPATH, "rb");
  172.  
  173.     // Si el archivo se a abierto con exito
  174.     if (savefile) {
  175.         // Borra el contenido previo
  176.         memset((void*)&CHECKSUM, 0, sizeof(CHECKSUM));
  177.         memset((void*)&GAMEOPTIONS, 0, sizeof(GAMEOPTIONS));
  178.         // Lee los datos
  179.         fread((void*)&CHECKSUM, sizeof(CHECKSUM), 1, savefile);
  180.         fread((void*)&GAMEOPTIONS, sizeof(GAMEOPTIONS), 1, savefile);
  181.     }
  182.  
  183.     // Cierra el archivo
  184.     fclose(savefile);
  185.  
  186. }
  187.  
  188.  
  189.  
  190. // Funcion CheckSavegameSRAM();
  191. void CheckSavegameSRAM(void) {
  192.  
  193.     // Variables
  194.     u32 checksum = 0;       // Checksum de los datos del juego
  195.  
  196.     // Carga los datos de la SRAM
  197.     if (USE_SRAM && !REG_DSIMODE) ReadSRAM();
  198.  
  199.     // Calcula el Checksum
  200.     checksum = SavedataChecksum();
  201.  
  202.     // Si hay discrepancias
  203.     if (
  204.         (checksum != CHECKSUM[0].value)
  205.         ||
  206.         (CHECKSUM[0].version != SAVEGAMEVERSION)
  207.         ||
  208.         (strcmp(CHECKSUM[0].magic, "SPIRITSDS") != 0)
  209.         ) {
  210.         // Inicializa los datos del juego
  211.         InitGameData();
  212.         // Guarda los datos
  213.         if (USE_SRAM && !REG_DSIMODE) WriteSRAM();
  214.     }
  215.  
  216. }
  217.  
  218.  
  219.  
  220. // Funcion WriteSRAM();
  221. void WriteSRAM(void) {
  222.  
  223.     // Variables
  224.     u16 adress = 0;         // Posicion en la SRAM
  225.     u16 i = 0;              // Indice
  226.     bool slot2 = false;     // Propietario actual del SLOT2
  227.  
  228.     // Alamacena el CHECKSUM
  229.     CHECKSUM[0].value = SavedataChecksum();
  230.  
  231.     // Si no lo es, haz al ARM9 propietario del SLOT2 y guarda el propietario actual
  232.     slot2 = (REG_EXMEMCNT & ARM7_OWNS_ROM) == 0;
  233.     sysSetCartOwner(true);
  234.  
  235.     // Copia los datos del bloque CHECKSUM
  236.     for (i = 0; i < sizeof(CHECKSUM); i ++) {
  237.         ((u8*)SRAM)[adress] = ((u8*)CHECKSUM)[i];
  238.         adress ++;
  239.     }
  240.  
  241.     // Copia los datos del bloque GAMEOPTIONS
  242.     for (i = 0; i < sizeof(GAMEOPTIONS); i ++) {
  243.         ((u8*)SRAM)[adress] = ((u8*)GAMEOPTIONS)[i];
  244.         adress ++;
  245.     }
  246.  
  247.     // Devuelve el propietario del SLOT2 al propietario anterior
  248.     sysSetCartOwner(slot2);
  249.  
  250. }
  251.  
  252.  
  253.  
  254. // Funcion WriteSRAM();
  255. void ReadSRAM(void) {
  256.  
  257.     // Variables
  258.     u16 adress = 0;         // Posicion en la SRAM
  259.     u16 i = 0;              // Indice
  260.     bool slot2 = false;     // Propietario actual del SLOT2
  261.  
  262.     // Borra el contenido previo
  263.     memset((void*)&CHECKSUM, 0, sizeof(CHECKSUM));
  264.     memset((void*)&GAMEOPTIONS, 0, sizeof(GAMEOPTIONS));
  265.  
  266.     // Si no lo es, haz al ARM9 propietario del SLOT2 y guarda el propietario actual
  267.     slot2 = (REG_EXMEMCNT & ARM7_OWNS_ROM) == 0;
  268.     sysSetCartOwner(true);
  269.  
  270.     // Copia los datos del bloque CHECKSUM
  271.     for (i = 0; i < sizeof(CHECKSUM); i ++) {
  272.         ((u8*)CHECKSUM)[i] = ((u8*)SRAM)[adress];
  273.         adress ++;
  274.     }
  275.  
  276.     // Copia los datos del bloque GAMEOPTIONS
  277.     for (i = 0; i < sizeof(GAMEOPTIONS); i ++) {
  278.         ((u8*)GAMEOPTIONS)[i] = ((u8*)SRAM)[adress];
  279.         adress ++;
  280.     }
  281.  
  282.     // Devuelve el propietario del SLOT2 al propietario anterior
  283.     sysSetCartOwner(slot2);
  284.  
  285. }
  286.  
  287.  
  288.  
  289. // Verifica si puedes escribir en FAT
  290. bool CheckFATWrite(const char* path) {
  291.  
  292.     // Variables
  293.     bool filefound = false;     // Existe el fichero
  294.     u16 l = 0;                  // Longitud del path al archivo
  295.     FILE* savefile;             // Puntero de archivo
  296.     char testfile[256];         // Nombre de archivo
  297.  
  298.     // Almacena el path
  299.     sprintf(testfile, path);
  300.  
  301.     // Añade la extension .CHK al archivo de verificacion
  302.     l = strlen(testfile);
  303.     testfile[(l - 3)] = 'c';
  304.     testfile[(l - 2)] = 'h';
  305.     testfile[(l - 1)] = 'k';
  306.  
  307.     // Verifica si puedes abrir en el archivo de verificacion
  308.     savefile = fopen(testfile, "rb");
  309.     if (savefile) {
  310.         filefound = true;
  311.     } else {
  312.         filefound = false;
  313.     }
  314.     fclose(savefile);
  315.  
  316.     // Si no puedes, crea uno e intentalo abrir de nuevo
  317.     if (!filefound) {
  318.         savefile = fopen(testfile, "wb");
  319.         fclose(savefile);
  320.         savefile = fopen(testfile, "rb");
  321.         if (savefile) filefound = true;
  322.         fclose(savefile);
  323.     }
  324.  
  325.     return filefound;
  326.  
  327. }
  328.  
  329.  
  330.  
  331. // Funcion SavedataChecksum();
  332. u32 SavedataChecksum(void) {
  333.  
  334.     // Variables
  335.     u16 i = 0;
  336.     u32 checksum = 0;
  337.  
  338.     // Checksum de los datos del bloque GAMEOPTIONS
  339.     for (i = 0; i < sizeof(GAMEOPTIONS); i ++) {
  340.         checksum += ((u8*)GAMEOPTIONS)[i];
  341.     }
  342.  
  343.     // Variables
  344.     return checksum;
  345.  
  346. }
  347.  
  348.  
  349.  
  350. // Funcion InitGameData();
  351. void InitGameData(void) {
  352.    
  353.     // Magic String del checksum
  354.     sprintf(CHECKSUM[0].magic, "SPIRITSDS");
  355.     CHECKSUM[0].magic[9] = '\0';
  356.  
  357.     // Identificador de la version
  358.     CHECKSUM[0].version = SAVEGAMEVERSION;
  359.  
  360.     // Opciones del juego por defecto
  361.     GAMEOPTIONS[0].remake = true;       // Modo Remake por defecto
  362.     GAMEOPTIONS[0].scanlines = 1;       // Scanlines a nivel 2
  363.  
  364.     // Inicializa el Idioma por defecto (basado en el del usuario)
  365.     if (NF_GetLanguage() == 5) {
  366.         GAMEOPTIONS[0].language = 0;    // Español
  367.     } else {
  368.         GAMEOPTIONS[0].language = 1;    // Ingles
  369.     }
  370.  
  371. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement