mirror of
https://github.com/RocketRobz/SuperAllStarPhotoStudio.git
synced 2025-06-18 17:15:35 -04:00
Test Styling Star save reading/writing
This commit is contained in:
parent
afcd476ee2
commit
fda330ea0a
43
include/tonccpy.h
Normal file
43
include/tonccpy.h
Normal file
@ -0,0 +1,43 @@
|
||||
//# Stuff you may not have yet.
|
||||
|
||||
#ifndef TONCCPY_H
|
||||
#define TONCCPY_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <3ds.h>
|
||||
|
||||
typedef unsigned int uint;
|
||||
#define BIT_MASK(len) ( (1<<(len))-1 )
|
||||
static inline u32 quad8(u8 x) { x |= x<<8; return x | x<<16; }
|
||||
|
||||
|
||||
//# Declarations and inlines.
|
||||
|
||||
void tonccpy(void *dst, const void *src, uint size);
|
||||
|
||||
void __toncset(void *dst, u32 fill, uint size);
|
||||
static inline void toncset(void *dst, u8 src, uint size);
|
||||
static inline void toncset16(void *dst, u16 src, uint size);
|
||||
static inline void toncset32(void *dst, u32 src, uint size);
|
||||
|
||||
|
||||
//! VRAM-safe memset, byte version. Size in bytes.
|
||||
static inline void toncset(void *dst, u8 src, uint size)
|
||||
{ __toncset(dst, quad8(src), size); }
|
||||
|
||||
//! VRAM-safe memset, halfword version. Size in hwords.
|
||||
static inline void toncset16(void *dst, u16 src, uint size)
|
||||
{ __toncset(dst, src|src<<16, size*2); }
|
||||
|
||||
//! VRAM-safe memset, word version. Size in words.
|
||||
static inline void toncset32(void *dst, u32 src, uint size)
|
||||
{ __toncset(dst, src, size*4); }
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
@ -6,6 +6,7 @@
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "gui.hpp"
|
||||
#include "savedata.h"
|
||||
|
||||
#define CONFIG_3D_SLIDERSTATE (*(float *)0x1FF81080)
|
||||
|
||||
@ -84,6 +85,7 @@ int main()
|
||||
//titleshot = title1shot;
|
||||
|
||||
int highlightedGame = 0;
|
||||
bool saveWritten = false;
|
||||
|
||||
int fadealpha = 255;
|
||||
int fadecolor = 0;
|
||||
@ -227,6 +229,19 @@ int main()
|
||||
if (fadealpha > 0) Draw_Rect(0, 0, 400, 240, C2D_Color32(fadecolor, fadecolor, fadecolor, fadealpha)); // Fade in/out effect
|
||||
Draw_EndFrame();
|
||||
|
||||
if (highlightedGame == 3 && !saveWritten) {
|
||||
readSS4Save();
|
||||
readSS4Character(0);
|
||||
if (ss4CharacterData.gender == 1) {
|
||||
ss4CharacterData.gender = 2; // Male
|
||||
} else {
|
||||
ss4CharacterData.gender = 1; // Female
|
||||
}
|
||||
writeSS4Character(0);
|
||||
writeSS4Save();
|
||||
saveWritten = true;
|
||||
}
|
||||
|
||||
if(!fadein) {
|
||||
if(hDown & KEY_B){
|
||||
screenmodebuffer = SCREEN_MODE_GAME_SELECT;
|
||||
@ -240,7 +255,7 @@ int main()
|
||||
bg_yPos -= 0.2;
|
||||
if(bg_yPos <= -136) bg_yPos = 0.0f;
|
||||
|
||||
if (fadein == true) {
|
||||
if (fadein) {
|
||||
fadealpha -= 6;
|
||||
if (fadealpha < 0) {
|
||||
fadealpha = 0;
|
||||
@ -254,6 +269,9 @@ int main()
|
||||
if (fadealpha > 255) {
|
||||
fadealpha = 255;
|
||||
screenmode = screenmodebuffer;
|
||||
if(screenmode == SCREEN_MODE_CHARACTER_SELECT) {
|
||||
saveWritten = false;
|
||||
}
|
||||
fadein = true;
|
||||
fadeout = false;
|
||||
}
|
||||
|
43
source/savedata.cpp
Normal file
43
source/savedata.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
#include <3ds.h>
|
||||
#include <stdio.h>
|
||||
#include <cstring>
|
||||
#include "savedata.h"
|
||||
#include "tonccpy.h"
|
||||
|
||||
ss3to4character ss4CharacterData;
|
||||
|
||||
char ss3Save[0x174000];
|
||||
char ss4Save[0xF0000];
|
||||
|
||||
void readSS4Save(void) {
|
||||
FILE* saveData = fopen("sdmc:/3ds/Checkpoint/extdata/0x01C25 Style Savvy Styling Star/SavvyManager/savedata.dat", "rb");
|
||||
fread(ss4Save, (int)sizeof(ss4Save), 1, saveData);
|
||||
fclose(saveData);
|
||||
}
|
||||
|
||||
void writeSS4Save(void) {
|
||||
FILE* saveData = fopen("sdmc:/3ds/Checkpoint/extdata/0x01C25 Style Savvy Styling Star/SavvyManager/savedata.dat", "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);
|
||||
}
|
||||
}
|
74
source/savedata.h
Normal file
74
source/savedata.h
Normal file
@ -0,0 +1,74 @@
|
||||
#ifndef SAVEDATA_H
|
||||
#define SAVEDATA_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <3ds.h>
|
||||
|
||||
typedef struct ss3to4character {
|
||||
u8 gender; // Gender (01=Female, 02=Male)
|
||||
u8 height; // Height (00=Character is invisible)
|
||||
u8 poseSet; // Pose set (01=Normal, 02=Cute, 03=Bold)
|
||||
u8 skinColor;
|
||||
u8 faceShape; // Face shape (03=Left, 01=Mid, 02=Right)
|
||||
u8 eyes;
|
||||
u8 mouthShape;
|
||||
u8 eyebrows;
|
||||
u8 faceMole; // Face mole (Female), Facial hair (Male)
|
||||
u8 freckles; // Unknown for Styling Star
|
||||
u8 mascaraColor;
|
||||
u8 unknownC;
|
||||
u8 unknownD;
|
||||
u8 eyeMakeupColor;
|
||||
u8 unknownF;
|
||||
u8 mascaraLength;
|
||||
u8 unknown11;
|
||||
u8 lipShine;
|
||||
u8 eyeColor;
|
||||
u8 eyebrowOverlay;
|
||||
u8 hairStyle;
|
||||
u8 hairFringe;
|
||||
u8 hairColorMain;
|
||||
u8 hairColorHighlights;
|
||||
u8 expessFreckles; // Show expressions for Fashion Forward, or freckles for Styling Star
|
||||
u8 nailColor;
|
||||
u8 eyeliner; // Eyeliner (00=Normal, 01=Double)
|
||||
u8 unknown1C;
|
||||
u16 inner;
|
||||
u16 top; // Top/Dress/Yukatas (Female), Yukatas/Dungarees (Male)
|
||||
u16 outer;
|
||||
u16 necklaceScarf; // Necklace/Scarf
|
||||
u16 gloves;
|
||||
u16 socks; // Socks/Leggings/Tights
|
||||
u16 skirtPants; // Skirt/Pants
|
||||
u16 shoes;
|
||||
u16 unknown2E;
|
||||
u16 hat;
|
||||
u16 glasses;
|
||||
u16 bow;
|
||||
u16 unknown36;
|
||||
u16 unknown38;
|
||||
u16 unknown3A;
|
||||
u8 bowPosition;
|
||||
u8 unknown3D;
|
||||
} ss3to4character;
|
||||
|
||||
extern ss3to4character ss4CharacterData;
|
||||
|
||||
extern char ss3Save[0x174000];
|
||||
extern char ss4Save[0xF0000];
|
||||
|
||||
extern void readSS4Save(void);
|
||||
extern void writeSS4Save(void);
|
||||
|
||||
extern void readSS4Character(u16 id);
|
||||
extern void writeSS4Character(u16 id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SAVEDATA_H
|
136
source/tonccpy.c
Normal file
136
source/tonccpy.c
Normal file
@ -0,0 +1,136 @@
|
||||
#include "tonccpy.h"
|
||||
//# tonccpy.c
|
||||
|
||||
//! VRAM-safe cpy.
|
||||
/*! This version mimics memcpy in functionality, with
|
||||
the benefit of working for VRAM as well. It is also
|
||||
slightly faster than the original memcpy, but faster
|
||||
implementations can be made.
|
||||
\param dst Destination pointer.
|
||||
\param src Source pointer.
|
||||
\param size Fill-length in bytes.
|
||||
\note The pointers and size need not be word-aligned.
|
||||
*/
|
||||
void tonccpy(void *dst, const void *src, uint size)
|
||||
{
|
||||
if(size==0 || dst==0 || src==0)
|
||||
return;
|
||||
|
||||
uint count;
|
||||
u16 *dst16; // hword destination
|
||||
u8 *src8; // byte source
|
||||
|
||||
// Ideal case: copy by 4x words. Leaves tail for later.
|
||||
if( ((u32)src|(u32)dst)%4==0 && size>=4)
|
||||
{
|
||||
u32 *src32= (u32*)src, *dst32= (u32*)dst;
|
||||
|
||||
count= size/4;
|
||||
uint tmp= count&3;
|
||||
count /= 4;
|
||||
|
||||
// Duff's Device, good friend!
|
||||
switch(tmp) {
|
||||
do { *dst32++ = *src32++;
|
||||
case 3: *dst32++ = *src32++;
|
||||
case 2: *dst32++ = *src32++;
|
||||
case 1: *dst32++ = *src32++;
|
||||
case 0: ; } while(count--);
|
||||
}
|
||||
|
||||
// Check for tail
|
||||
size &= 3;
|
||||
if(size == 0)
|
||||
return;
|
||||
|
||||
src8= (u8*)src32;
|
||||
dst16= (u16*)dst32;
|
||||
}
|
||||
else // Unaligned.
|
||||
{
|
||||
uint dstOfs= (u32)dst&1;
|
||||
src8= (u8*)src;
|
||||
dst16= (u16*)(dst-dstOfs);
|
||||
|
||||
// Head: 1 byte.
|
||||
if(dstOfs != 0)
|
||||
{
|
||||
*dst16= (*dst16 & 0xFF) | *src8++<<8;
|
||||
dst16++;
|
||||
if(--size==0)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Unaligned main: copy by 2x byte.
|
||||
count= size/2;
|
||||
while(count--)
|
||||
{
|
||||
*dst16++ = src8[0] | src8[1]<<8;
|
||||
src8 += 2;
|
||||
}
|
||||
|
||||
// Tail: 1 byte.
|
||||
if(size&1)
|
||||
*dst16= (*dst16 &~ 0xFF) | *src8;
|
||||
}
|
||||
//# toncset.c
|
||||
|
||||
//! VRAM-safe memset, internal routine.
|
||||
/*! This version mimics memset in functionality, with
|
||||
the benefit of working for VRAM as well. It is also
|
||||
slightly faster than the original memset.
|
||||
\param dst Destination pointer.
|
||||
\param fill Word to fill with.
|
||||
\param size Fill-length in bytes.
|
||||
\note The \a dst pointer and \a size need not be
|
||||
word-aligned. In the case of unaligned fills, \a fill
|
||||
will be masked off to match the situation.
|
||||
*/
|
||||
void __toncset(void *dst, u32 fill, uint size)
|
||||
{
|
||||
if(size==0 || dst==0)
|
||||
return;
|
||||
|
||||
uint left= (u32)dst&3;
|
||||
u32 *dst32= (u32*)(dst-left);
|
||||
u32 count, mask;
|
||||
|
||||
// Unaligned head.
|
||||
if(left != 0)
|
||||
{
|
||||
// Adjust for very small stint.
|
||||
if(left+size<4)
|
||||
{
|
||||
mask= BIT_MASK(size*8)<<(left*8);
|
||||
*dst32= (*dst32 &~ mask) | (fill & mask);
|
||||
return;
|
||||
}
|
||||
|
||||
mask= BIT_MASK(left*8);
|
||||
*dst32= (*dst32 & mask) | (fill&~mask);
|
||||
dst32++;
|
||||
size -= 4-left;
|
||||
}
|
||||
|
||||
// Main stint.
|
||||
count= size/4;
|
||||
uint tmp= count&3;
|
||||
count /= 4;
|
||||
|
||||
switch(tmp) {
|
||||
do { *dst32++ = fill;
|
||||
case 3: *dst32++ = fill;
|
||||
case 2: *dst32++ = fill;
|
||||
case 1: *dst32++ = fill;
|
||||
case 0: ; } while(count--);
|
||||
}
|
||||
|
||||
// Tail
|
||||
size &= 3;
|
||||
if(size)
|
||||
{
|
||||
mask= BIT_MASK(size*8);
|
||||
*dst32= (*dst32 &~ mask) | (fill & mask);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user