mirror of
https://github.com/RocketRobz/SavvyManager.git
synced 2025-06-18 17:15:34 -04:00
401 lines
9.7 KiB
C++
401 lines
9.7 KiB
C++
#include <3ds.h>
|
|
#include <stdio.h>
|
|
#include <cstring>
|
|
#include "savedata.h"
|
|
#include "tonccpy.h"
|
|
|
|
ss2character ss2CharacterData;
|
|
ss3to4character ss4CharacterData;
|
|
|
|
ss3to4emblem emblemData;
|
|
|
|
const char* ss1SavePath;
|
|
|
|
char ss1Save[0x100000];
|
|
char ss2Save[0x31736];
|
|
char ss3Save[0x174000];
|
|
char ss4Save[0xF0000];
|
|
|
|
char ss1PlayerName[10] = {0};
|
|
char ss2PlayerName[10] = {0};
|
|
char ss3PlayerName[10] = {0};
|
|
char ss4PlayerName[10] = {0};
|
|
|
|
static bool ss1SaveRead = false;
|
|
static bool ss2SaveRead = false;
|
|
static bool ss3SaveRead = false;
|
|
static bool ss4SaveRead = false;
|
|
|
|
/*
|
|
Style Savvy
|
|
*/
|
|
void readSS1Save(void) {
|
|
if (ss1SaveRead) return;
|
|
|
|
FILE* saveData = fopen(ss1SavePath, "rb");
|
|
fread(ss1Save, (int)sizeof(ss1Save), 1, saveData);
|
|
fclose(saveData);
|
|
|
|
// Get playable character's name
|
|
if (ss1Save[0x204] == 0x86 || ss1Save[0x204] == 0x87) {
|
|
for (int i = 0; i < 9; i++) {
|
|
ss1PlayerName[i] = ss1Save[0x3AB8+(i)];
|
|
}
|
|
} else {
|
|
for (int i = 0; i < 9; i++) {
|
|
ss1PlayerName[i] = ss1Save[0x63B8+(i)];
|
|
}
|
|
}
|
|
|
|
ss2SaveRead = true;
|
|
}
|
|
|
|
void writeSS1Save(void) {
|
|
remove(ss1SavePath);
|
|
FILE* saveData = fopen(ss1SavePath, "wb");
|
|
fwrite(ss1Save, (int)sizeof(ss1Save), 1, saveData);
|
|
fclose(saveData);
|
|
}
|
|
|
|
/*
|
|
Style Savvy: Trendsetters
|
|
*/
|
|
void readSS2Save(void) {
|
|
if (ss2SaveRead) return;
|
|
|
|
FILE* saveData = fopen(ss2SavePath, "rb");
|
|
fread(ss2Save, (int)sizeof(ss2Save), 1, saveData);
|
|
fclose(saveData);
|
|
|
|
// Get playable character's name
|
|
for (int i = 0; i < 9; i++) {
|
|
ss2PlayerName[i] = ss2Save[0x1AC8+(i*2)];
|
|
}
|
|
|
|
ss2SaveRead = true;
|
|
}
|
|
|
|
void writeSS2Save(void) {
|
|
remove(ss2SavePath);
|
|
FILE* saveData = fopen(ss2SavePath, "wb");
|
|
fwrite(ss2Save, (int)sizeof(ss2Save), 1, saveData);
|
|
fclose(saveData);
|
|
}
|
|
|
|
void readSS2Character(void) {
|
|
// Playable character
|
|
tonccpy(&ss2CharacterData, (char*)ss2Save+(0x102), 0x3);
|
|
tonccpy((char*)&ss2CharacterData+0x3, (char*)ss2Save+(0x106), 0x1);
|
|
tonccpy((char*)&ss2CharacterData+0x4, (char*)ss2Save+(0x130), 0x18);
|
|
tonccpy((char*)&ss2CharacterData+0x1C, (char*)ss2Save+(0x188), 0x20);
|
|
}
|
|
|
|
void writeSS2Character(void) {
|
|
// Playable character
|
|
tonccpy((char*)ss2Save+(0x102), &ss2CharacterData, 0x3);
|
|
tonccpy((char*)ss2Save+(0x106), (char*)&ss2CharacterData+0x3, 0x1);
|
|
tonccpy((char*)ss2Save+(0x130), (char*)&ss2CharacterData+0x4, 0x18);
|
|
tonccpy((char*)ss2Save+(0x188), (char*)&ss2CharacterData+0x1C, 0x20);
|
|
tonccpy((char*)ss2Save+(0x1C8), (char*)&ss2CharacterData+0x1C, 0x20);
|
|
tonccpy((char*)ss2Save+(0x208), (char*)&ss2CharacterData+0x1C, 0x20);
|
|
tonccpy((char*)ss2Save+(0x248), (char*)&ss2CharacterData+0x1C, 0x20);
|
|
}
|
|
|
|
void readSS2CharacterFile(const char* filename) {
|
|
FILE* characterData = fopen(filename, "rb");
|
|
if (!characterData) return;
|
|
|
|
// Playable character
|
|
fseek(characterData, 0, SEEK_SET);
|
|
fread((char*)ss2Save+(0x102), 0x3, 1, characterData);
|
|
fseek(characterData, 3, SEEK_SET);
|
|
fread((char*)ss2Save+(0x106), 0x1, 1, characterData);
|
|
fread((char*)ss2Save+(0x130), 0x18, 1, characterData);
|
|
fread((char*)ss2Save+(0x188), 0x20, 1, characterData);
|
|
tonccpy((char*)ss2Save+(0x1C8), (char*)ss2Save+(0x188), 0x20);
|
|
tonccpy((char*)ss2Save+(0x208), (char*)ss2Save+(0x188), 0x20);
|
|
tonccpy((char*)ss2Save+(0x248), (char*)ss2Save+(0x188), 0x20);
|
|
|
|
fclose(characterData);
|
|
}
|
|
|
|
void writeSS2CharacterFile(const char* filename) {
|
|
FILE* characterData = fopen(filename, "wb");
|
|
if (!characterData) return;
|
|
|
|
// Playable character
|
|
fwrite((char*)ss2Save+(0x102), 0x3, 1, characterData);
|
|
fwrite((char*)ss2Save+(0x106), 0x1, 1, characterData);
|
|
fwrite((char*)ss2Save+(0x130), 0x18, 1, characterData);
|
|
fwrite((char*)ss2Save+(0x188), 0x20, 1, characterData);
|
|
|
|
fclose(characterData);
|
|
}
|
|
|
|
bool getSS2CharacterGender(void) {
|
|
if ((strcmp(ss2PlayerName, "Robz") == 0) && (ss2CharacterData.hairStyle == 0x07)) {
|
|
return true; // Robz is male, so return male
|
|
}
|
|
|
|
// true = male, false = female
|
|
return (ss2Save[0x102] == 2);
|
|
}
|
|
|
|
|
|
/*
|
|
Style Savvy: Fashion Forward
|
|
*/
|
|
void readSS3Save(void) {
|
|
if (ss3SaveRead) return;
|
|
|
|
FILE* saveData = fopen(ss3SavePath, "rb");
|
|
fread(ss3Save, (int)sizeof(ss3Save), 1, saveData);
|
|
fclose(saveData);
|
|
|
|
// Get playable character's name
|
|
for (int i = 0; i < 9; i++) {
|
|
ss3PlayerName[i] = ss3Save[0x54980+(i*2)];
|
|
}
|
|
|
|
ss3SaveRead = true;
|
|
}
|
|
|
|
void writeSS3Save(void) {
|
|
remove(ss3SavePath);
|
|
FILE* saveData = fopen(ss3SavePath, "wb");
|
|
fwrite(ss3Save, (int)sizeof(ss3Save), 1, saveData);
|
|
fclose(saveData);
|
|
}
|
|
|
|
void readSS3Character(u16 id) {
|
|
if (id == 0) {
|
|
// Playable character
|
|
tonccpy(&ss4CharacterData, (char*)ss3Save+(0x54A22), 0x36);
|
|
} else {
|
|
// Non-playable character
|
|
tonccpy(&ss4CharacterData, (char*)ss3Save+(0x55EFE + (0x110*id)), 0x36);
|
|
}
|
|
}
|
|
|
|
void writeSS3Character(u16 id) {
|
|
if (id == 0) {
|
|
// Playable character
|
|
tonccpy((char*)ss3Save+(0x54A22), &ss4CharacterData, 0x36);
|
|
} else {
|
|
// Non-playable character
|
|
tonccpy((char*)ss3Save+(0x55EFE + (0x110*id)), &ss4CharacterData, 0x36);
|
|
}
|
|
}
|
|
|
|
void readSS3CharacterFile(u16 id, const char* filename) {
|
|
FILE* characterData = fopen(filename, "rb");
|
|
if (!characterData) return;
|
|
|
|
if (id == 0) {
|
|
// Playable character
|
|
fread((char*)ss3Save+(0x54A22), 0x36, 1, characterData);
|
|
} else {
|
|
// Non-playable character
|
|
fread((char*)ss3Save+(0x55EFE + (0x110*id)), 0x36, 1, characterData);
|
|
}
|
|
fclose(characterData);
|
|
}
|
|
|
|
void writeSS3CharacterFile(u16 id, const char* filename) {
|
|
FILE* characterData = fopen(filename, "wb");
|
|
if (!characterData) return;
|
|
|
|
if (id == 0) {
|
|
// Playable character
|
|
fwrite((char*)ss3Save+(0x54A22), 0x36, 1, characterData);
|
|
} else {
|
|
// Non-playable character
|
|
fwrite((char*)ss3Save+(0x55EFE + (0x110*id)), 0x36, 1, characterData);
|
|
}
|
|
fclose(characterData);
|
|
}
|
|
|
|
bool getSS3CharacterGender(u16 id) {
|
|
readSS3Character(id);
|
|
|
|
if ((id == 0) && (strcmp(ss3PlayerName, "Robz") == 0) && (ss4CharacterData.hairStyle == 0x27)) {
|
|
return true; // Robz is male, so return male
|
|
}
|
|
|
|
// true = male, false = female
|
|
return (ss4CharacterData.gender == 2);
|
|
}
|
|
|
|
void readSS3Emblem(void) {
|
|
tonccpy(&emblemData, (char*)ss3Save+(0x2ABB8), 0x804);
|
|
}
|
|
|
|
void writeSS3Emblem(void) {
|
|
tonccpy((char*)ss3Save+(0x2ABB8), &emblemData, 0x804);
|
|
}
|
|
|
|
void readSS3EmblemFile(const char* filename) {
|
|
FILE* emblemData = fopen(filename, "rb");
|
|
if (!emblemData) return;
|
|
|
|
fread((char*)ss3Save+(0x2ABB8), 0x804, 1, emblemData);
|
|
fclose(emblemData);
|
|
}
|
|
|
|
void writeSS3EmblemFile(const char* filename) {
|
|
FILE* emblemData = fopen(filename, "wb");
|
|
if (!emblemData) return;
|
|
|
|
fwrite((char*)ss3Save+(0x2ABB8), 0x804, 1, emblemData);
|
|
fclose(emblemData);
|
|
}
|
|
|
|
|
|
/*
|
|
Style Savvy: Styling Star
|
|
*/
|
|
void readSS4Save(void) {
|
|
if (ss4SaveRead) return;
|
|
|
|
FILE* saveData = fopen(ss4SavePath, "rb");
|
|
fread(ss4Save, (int)sizeof(ss4Save), 1, saveData);
|
|
fclose(saveData);
|
|
|
|
// Get playable character's name
|
|
for (int i = 0; i < 9; i++) {
|
|
ss4PlayerName[i] = ss4Save[0x24370+(i*2)];
|
|
}
|
|
|
|
ss4SaveRead = true;
|
|
}
|
|
|
|
void writeSS4Save(void) {
|
|
remove(ss4SavePath);
|
|
FILE* saveData = fopen(ss4SavePath, "wb");
|
|
fwrite(ss4Save, (int)sizeof(ss4Save), 1, saveData);
|
|
fclose(saveData);
|
|
}
|
|
|
|
void readSS4Character(u16 id) {
|
|
if (id == 0) {
|
|
// Playable character
|
|
tonccpy(&ss4CharacterData, (char*)ss4Save+(0x2440A), 0x3E);
|
|
} else {
|
|
// Non-playable character
|
|
tonccpy(&ss4CharacterData, (char*)ss4Save+(0x273EE + (0x1F8*id)), 0x3E);
|
|
}
|
|
}
|
|
|
|
void writeSS4Character(u16 id) {
|
|
if (id == 0) {
|
|
// Playable character
|
|
tonccpy((char*)ss4Save+(0x2440A), &ss4CharacterData, 0x3E);
|
|
} else {
|
|
// Non-playable character
|
|
tonccpy((char*)ss4Save+(0x273EE + (0x1F8*id)), &ss4CharacterData, 0x3E);
|
|
}
|
|
}
|
|
|
|
void readSS4CharacterFile(u16 id, const char* filename) {
|
|
FILE* characterData = fopen(filename, "rb");
|
|
if (!characterData) return;
|
|
|
|
if (id == 0) {
|
|
// Playable character
|
|
fread((char*)ss4Save+(0x2440A), 0x3E, 1, characterData);
|
|
} else {
|
|
// Non-playable character
|
|
fread((char*)ss4Save+(0x273EE + (0x1F8*id)), 0x3E, 1, characterData);
|
|
}
|
|
fclose(characterData);
|
|
}
|
|
|
|
void writeSS4CharacterFile(u16 id, const char* filename) {
|
|
FILE* characterData = fopen(filename, "wb");
|
|
if (!characterData) return;
|
|
|
|
if (id == 0) {
|
|
// Playable character
|
|
fwrite((char*)ss4Save+(0x2440A), 0x3E, 1, characterData);
|
|
} else {
|
|
// Non-playable character
|
|
fwrite((char*)ss4Save+(0x273EE + (0x1F8*id)), 0x3E, 1, characterData);
|
|
}
|
|
fclose(characterData);
|
|
}
|
|
|
|
bool getSS4CharacterGender(u16 id) {
|
|
readSS4Character(id);
|
|
|
|
if ((id == 0) && (strcmp(ss4PlayerName, "Robz") == 0) && (ss4CharacterData.hairStyle == 0x6D)) {
|
|
return true; // Robz is male, so return male
|
|
}
|
|
|
|
// true = male, false = female
|
|
return (ss4CharacterData.gender == 2);
|
|
}
|
|
|
|
void readSS4Emblem(int id) {
|
|
switch (id) {
|
|
case 0:
|
|
tonccpy(&emblemData, (char*)ss4Save+(0x228FC), 0x804);
|
|
break;
|
|
case 1:
|
|
tonccpy(&emblemData, (char*)ss4Save+(0x23100), 0x804);
|
|
break;
|
|
case 2:
|
|
tonccpy(&emblemData, (char*)ss4Save+(0x23904), 0x804);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void writeSS4Emblem(int id) {
|
|
switch (id) {
|
|
case 0:
|
|
tonccpy((char*)ss4Save+(0x228FC), &emblemData, 0x804);
|
|
break;
|
|
case 1:
|
|
tonccpy((char*)ss4Save+(0x23100), &emblemData, 0x804);
|
|
break;
|
|
case 2:
|
|
tonccpy((char*)ss4Save+(0x23904), &emblemData, 0x804);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void readSS4EmblemFile(int id, const char* filename) {
|
|
FILE* emblemData = fopen(filename, "rb");
|
|
if (!emblemData) return;
|
|
|
|
switch (id) {
|
|
case 0:
|
|
fread((char*)ss4Save+(0x228FC), 0x804, 1, emblemData);
|
|
break;
|
|
case 1:
|
|
fread((char*)ss4Save+(0x23100), 0x804, 1, emblemData);
|
|
break;
|
|
case 2:
|
|
fread((char*)ss4Save+(0x23904), 0x804, 1, emblemData);
|
|
break;
|
|
}
|
|
fclose(emblemData);
|
|
}
|
|
|
|
void writeSS4EmblemFile(int id, const char* filename) {
|
|
FILE* emblemData = fopen(filename, "wb");
|
|
if (!emblemData) return;
|
|
|
|
switch (id) {
|
|
case 0:
|
|
fwrite((char*)ss4Save+(0x228FC), 0x804, 1, emblemData);
|
|
break;
|
|
case 1:
|
|
fwrite((char*)ss4Save+(0x23100), 0x804, 1, emblemData);
|
|
break;
|
|
case 2:
|
|
fwrite((char*)ss4Save+(0x23904), 0x804, 1, emblemData);
|
|
break;
|
|
}
|
|
fclose(emblemData);
|
|
}
|