Skip to content

Commit 388c9d8

Browse files
committed
Made the UI, fixed some things
1 parent 7c8d626 commit 388c9d8

File tree

5 files changed

+224
-113
lines changed

5 files changed

+224
-113
lines changed

app/build-cia.rsf

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
BasicInfo:
2-
Title : "TSVT"
2+
Title : "TWLSaveTool"
33
CompanyCode : "00"
4-
ProductCode : "CTR-N-TSVT"
4+
ProductCode : "TWLSaveTool"
55
ContentType : Application # Application / SystemUpdate / Manual / Child / Trial
66
Logo : Nintendo # Nintendo / Licensed / Distributed / iQue / iQueForSystem
77

@@ -23,7 +23,7 @@ CardInfo:
2323
Option:
2424
UseOnSD : true # true if App is to be installed to SD
2525
EnableCompress : true # Compresses exefs code
26-
FreeProductCode : false # Removes limitations on ProductCode
26+
FreeProductCode : true # Removes limitations on ProductCode
2727
EnableCrypt : false # Enables encryption for NCCH and CIA
2828
MediaFootPadding : false # If true CCI files are created with padding
2929

include/TWLCard.h

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
#pragma once
2+
23
#include <3ds.h>
34
#include <string>
45
#include <utility>
56
#include <algorithm>
67
#include "errors.h"
78

9+
extern const int validSizes[7];
810

911
namespace TWLCard {
1012
struct Header {
11-
std::string gameTitle, gameCode, makerCode;
13+
std::string gameTitle, gameCode, makerCode;
14+
bool isTWL; // "DSi enhanced"
15+
16+
std::string generateCodeName(void) const;
1217
Header(u8* data = NULL);
1318
};
1419

@@ -19,8 +24,52 @@ namespace TWLCard {
1924
void closeSaveFile(Handle f);
2025

2126
u64 getSaveFileSize(void);
22-
void readSaveFile(u8* out, u64 nb = 0);
23-
void writeToSaveFile(u8* in, u64 nb = 0);
27+
u64 getSPISize(void);
28+
29+
template<class CallbackT>
30+
void readSaveFile(u8* out, u64 nb, CallbackT cb){
31+
Handle f = openSaveFile(FS_OPEN_READ);
32+
Result res;
33+
34+
u32 bytesRead;
35+
36+
u64 offset = 0;
37+
u64 spiSize = getSPISize();
38+
39+
for(offset = 0; offset < nb; offset += 512){
40+
u64 expected = (nb-offset < 512) ? (nb-offset) : 512;
41+
res = FSFILE_Read(f, &bytesRead, offset, out+offset, expected);
42+
if(res != 0){ closeSaveFile(f); throw Error(res,__FILE__, __LINE__); }
43+
if(expected != bytesRead) { closeSaveFile(f); throw std::runtime_error("too few bytes were read"); }
44+
cb(offset, nb);
45+
}
46+
cb(nb,nb);
47+
48+
closeSaveFile(f);
49+
}
50+
51+
template<class CallbackT>
52+
void writeToSaveFile(u8* in, u64 nb, CallbackT cb){
53+
Handle f = openSaveFile(FS_OPEN_WRITE);
54+
Result res;
55+
56+
u32 bytesWritten;
57+
58+
u64 offset = 0;
59+
60+
for(offset = 0; offset < nb; offset += 512){
61+
u64 expected = (nb-offset < 512) ? (nb-offset) : 512;
62+
res = FSFILE_Write(f, &bytesWritten, offset, in+offset, expected, FS_WRITE_FLUSH);
63+
if(res != 0){ closeSaveFile(f); throw Error(res,__FILE__, __LINE__); }
64+
if(expected != bytesWritten) { closeSaveFile(f); throw std::runtime_error("too few bytes were written"); }
65+
cb(offset, nb);
66+
}
67+
68+
cb(nb, nb);
69+
70+
closeSaveFile(f);
71+
}
72+
2473
}
2574

2675

include/errors.h

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,29 @@
1-
#pragma once
2-
#include <3ds.h>
3-
#include <stdexcept>
4-
1+
#pragma once
2+
#include <3ds.h>
3+
#include <stdexcept>
4+
5+
56
struct Error : public std::runtime_error {
6-
Error(u32 code) : std::runtime_error("It failed"), errorCode(code) {}
7+
Error(u32 code, const char* fn, int l) : std::runtime_error("It failed"), errorCode(code), fileName(fn), line(l) {}
78

8-
u32 getErrorCode(void) const throw(){
9+
u32 getErrorCode(void) const throw(){
910
return errorCode;
1011
}
1112

13+
const char* getFileName(void) const throw(){
14+
return fileName;
15+
}
16+
17+
int getLine(void) const throw(){
18+
return line;
19+
}
20+
1221
virtual const char* what() const throw(){
1322
return "It failed";
1423
}
1524

1625
protected:
1726
u32 errorCode;
27+
const char* fileName;
28+
int line;
1829
};

source/TWLCard.cpp

Lines changed: 47 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
#include "TWLCard.h"
22

3+
#include "games.h"
4+
5+
const int validSizes[7] = { 512, 8192, 65536, 262144, 524288, 1048576, 8388608 };
6+
7+
#define __FILE__ "TWLCard.cpp"
38
namespace TWLCard {
49
Header::Header(u8* data) {
510
if(data == NULL) return;
@@ -12,85 +17,79 @@ namespace TWLCard {
1217
gameTitle = std::string(in1);
1318
gameCode = std::string(in2);
1419
makerCode = std::string(in3);
20+
isTWL = (data[0x12] & 0x2) != 0;
21+
}
22+
23+
std::string Header::generateCodeName(void) const {
24+
using std::string;
25+
string first = (isTWL) ? string("TWL") : string("NTR");
26+
return first + string("-") + gameCode + string("-") + makerCode;
1527
}
1628

1729

1830
bool isCardTWL(void) {
1931
FS_CardType t;
2032
Result res = FSUSER_GetCardType(&t);
21-
if(res != 0) throw Error(res);
33+
if(res != 0) throw Error(res,__FILE__, __LINE__);
2234
return t == CARD_TWL;
2335
}
2436

2537
Header getHeader(void) {
26-
u8 data[18] = {0};
27-
Result res = FSUSER_GetLegacyRomHeader2(18, MEDIATYPE_GAME_CARD, 0LL, data);
28-
if(res != 0) throw Error(res);
29-
return Header(data);
38+
u8* data = new u8[0x3b4];
39+
Result res = FSUSER_GetLegacyRomHeader(MEDIATYPE_GAME_CARD, 0LL, data);
40+
if(res != 0) throw Error(res,__FILE__, __LINE__);
41+
Header ret(data);
42+
delete[] data;
43+
return ret;
3044
}
3145

3246
Handle openSaveFile(u32 openFlags) {
3347
Handle f;
3448
Result res = FSUSER_OpenFileDirectly(&f, (FS_Archive){ARCHIVE_CARD_SPIFS, fsMakePath(PATH_EMPTY, NULL)},
3549
fsMakePath(PATH_UTF16, L"/"), openFlags, 0);
3650

37-
if(res != 0) throw Error(res);
51+
if(res != 0) throw Error(res,__FILE__, __LINE__);
3852
return f;
3953
}
4054

4155
void closeSaveFile(Handle f) {
4256
Result res = FSFILE_Close(f);
43-
if(res != 0) throw Error(res);
57+
if(res != 0) throw Error(res,__FILE__, __LINE__);
4458
}
4559

4660
u64 getSaveFileSize(void) {
47-
Handle f = openSaveFile(FS_OPEN_READ);
48-
u64 sz;
49-
Result res = FSFILE_GetSize(f, &sz);
50-
if(res != 0) throw Error(res);
51-
closeSaveFile(f);
52-
return sz;
53-
}
54-
55-
void readSaveFile(u8* out, u64 nb) {
56-
Handle f = openSaveFile(FS_OPEN_READ);
57-
Result res;
58-
59-
if(nb == 0){
60-
FSFILE_GetSize(f, &nb);
61-
if(res != 0) throw Error(res);
62-
}
61+
int sz = 0;
62+
u8* buf = new u8[512];
63+
u8* buf2 = new u8[512];
6364

65+
Handle f;
6466
u32 bytesRead;
67+
if(FSUSER_OpenFileDirectly(&f, (FS_Archive){ARCHIVE_CARD_SPIFS, fsMakePath(PATH_EMPTY, NULL)},
68+
fsMakePath(PATH_UTF16, L"/"), FS_OPEN_READ, 0) != 0) goto end1;
6569

66-
res = FSFILE_Read(f, &bytesRead, 0LL, out, (u32)nb);
67-
68-
if(res != 0) throw Error(res);
69-
if(nb != bytesRead) throw std::runtime_error("too few bytes were read");
7070

71-
closeSaveFile(f);
71+
if(FSFILE_Read(f, &bytesRead, 0LL, buf, 512) != 0 || bytesRead != 512) goto end;
72+
73+
for(int offset : validSizes){
74+
if(FSFILE_Read(f, &bytesRead, offset, buf2, 512) != 0 || bytesRead != 512) goto end;
75+
if(std::equal(buf, buf+512, buf2)){
76+
sz = offset;
77+
break;
78+
}
79+
}
80+
end: FSFILE_Close(f);
81+
end1:
82+
delete[] buf;
83+
delete[] buf2;
84+
return (u64) sz;
7285
}
7386

74-
void writeToSaveFile(u8* out, u64 nb) {
75-
if(nb == 0)
76-
nb = getSaveFileSize();
77-
78-
Handle f = openSaveFile(FS_OPEN_WRITE);
79-
Result res;
80-
81-
if(nb == 0){
82-
FSFILE_GetSize(f, &nb);
83-
if(res != 0) throw Error(res);
84-
}
85-
86-
u32 bytesWritten;
87-
88-
res = FSFILE_Write(f, &bytesWritten, 0LL, out, (u32)nb, FS_WRITE_FLUSH);
89-
90-
if(res != 0) throw Error(res);
91-
if(nb != bytesWritten) throw std::runtime_error("too few bytes were written");
92-
87+
u64 getSPISize(void){
88+
Handle f = openSaveFile(FS_OPEN_READ);
89+
u64 sz;
90+
Result res = FSFILE_GetSize(f, &sz);
91+
if(res != 0) throw Error(res,__FILE__, __LINE__);
9392
closeSaveFile(f);
93+
return sz;
9494
}
95-
9695
}

0 commit comments

Comments
 (0)