Skip to content

Commit 38ecff0

Browse files
See desc for more.
- Rework the Checksum Calculation function. - Begin work on NDS version. - Some Appearance work for the GBA version.
1 parent a7cee9f commit 38ecff0

File tree

14 files changed

+409
-189
lines changed

14 files changed

+409
-189
lines changed

include/Strings.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ namespace Strings {
3636
extern const std::vector<std::string> GBAEpisodeNames_DE, GBAEpisodeNames_EN; // GBA Episodes.
3737
extern const std::vector<std::string> GBASkillPointNames_DE, GBASkillPointNames_EN; // GBA Skill Points.
3838
extern const std::vector<std::string> GBAItemNames_EN; // GBA Item Names.
39+
40+
extern const std::vector<std::string> NDSSkillPointNames_EN;
3941
};
4042

4143
#endif

include/gba/GBASlot.hpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,36 @@ class GBASlot {
5050
std::string Name() const;
5151
void Name(const std::string &V);
5252

53+
uint8_t Hairstyle() const;
54+
void Hairstyle(const uint8_t V);
55+
56+
uint8_t Shirtcolor3() const;
57+
void Shirtcolor3(const uint8_t V);
58+
59+
uint8_t Tan() const;
60+
void Tan(const uint8_t V);
61+
62+
uint8_t Shirtcolor2() const;
63+
void Shirtcolor2(const uint8_t V);
64+
65+
uint8_t Haircolor() const;
66+
void Haircolor(const uint8_t V);
67+
68+
uint8_t Hatcolor() const;
69+
void Hatcolor(const uint8_t V);
70+
71+
uint8_t Shirt() const;
72+
void Shirt(const uint8_t V);
73+
74+
uint8_t Shirtcolor1() const;
75+
void Shirtcolor1(const uint8_t V);
76+
77+
uint8_t Pants() const;
78+
void Pants(const uint8_t V);
79+
80+
uint8_t Pantscolor() const;
81+
void Pantscolor(const uint8_t V);
82+
5383
uint8_t Confidence() const;
5484
void Confidence(const uint8_t V);
5585

@@ -71,6 +101,9 @@ class GBASlot {
71101
uint8_t Sanity() const;
72102
void Sanity(const uint8_t V);
73103

104+
uint8_t Aspiration() const;
105+
void Aspiration(const uint8_t V);
106+
74107
/* Items. */
75108
std::unique_ptr<GBAItem> PawnShop() const;
76109
std::unique_ptr<GBAItem> Saloon() const;

include/nds/NDSSav.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,10 @@
3232
class NDSSAV {
3333
public:
3434
NDSSAV(const std::string &SAVFile);
35+
int8_t FetchSlot(const uint8_t SAVSlot);
3536

3637
/* Core Returns and Actions. */
37-
std::unique_ptr<NDSSlot> GetSlot(const uint8_t Slot);
38+
std::unique_ptr<NDSSlot> Slot(const uint8_t Slot);
3839
void Finish();
3940
bool SlotExist(const uint8_t Slot);
4041

@@ -50,6 +51,7 @@ class NDSSAV {
5051
bool SAVValid = false, SAVChangesMade = false;
5152

5253
static constexpr uint8_t SlotIdent[8] = { 0x64, 0x61, 0x74, 0x0, 0x20, 0x0, 0x0, 0x0 };
54+
int8_t Slots[3] = { -1, -1, -1 };
5355
};
5456

5557
#endif

include/nds/NDSSlot.hpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,39 @@ class NDSSlot {
3333
public:
3434
NDSSlot(const uint8_t Slot) : Slot(Slot), Offs(Slot * 0x1000) { };
3535

36+
uint32_t Simoleons() const;
37+
void Simoleons(const uint32_t V);
38+
39+
std::string Name() const;
40+
void Name(const std::string &V);
41+
42+
uint8_t Fuelrods() const;
43+
void Fuelrods(const uint8_t V);
44+
45+
uint8_t Plates() const;
46+
void Plates(const uint8_t V);
47+
48+
uint8_t Gourds() const;
49+
void Gourds(const uint8_t V);
50+
51+
uint8_t Spaceship() const;
52+
void Spaceship(const uint8_t V);
53+
54+
uint8_t Creativity() const;
55+
void Creativity(const uint8_t V);
56+
57+
uint8_t Business() const;
58+
void Business(const uint8_t V);
59+
60+
uint8_t Body() const;
61+
void Body(const uint8_t V);
62+
63+
uint8_t Charisma() const;
64+
void Charisma(const uint8_t V);
65+
66+
uint8_t Mechanical() const;
67+
void Mechanical(const uint8_t V);
68+
3669
bool FixChecksum();
3770
private:
3871
uint8_t Slot = 0;

include/shared/Checksum.hpp

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -28,25 +28,10 @@
2828
#define _SIM2EDITOR_CPP_CORE_CHECKSUM_HPP
2929

3030
#include "CoreCommon.hpp"
31+
#include <vector>
3132

3233
namespace Checksum {
33-
/* GBA Main Slot Checksum. */
34-
uint16_t CalcGBASlot(const uint8_t *Buffer, const uint8_t Slot);
35-
bool GBASlotChecksumValid(const uint8_t *Buffer, const uint8_t Slot, const uint16_t CHKS);
36-
37-
/* GBA Settings Checksum Calculation. */
38-
uint16_t CalcGBASettings(const uint8_t *Buffer);
39-
bool GBASettingsValid(const uint8_t *Buffer, const uint16_t CHKS);
40-
41-
/* NDS Checksum. The NDS version has multiple ones though. */
42-
uint16_t CalcNDSSlot(const uint8_t *Buffer, const uint8_t Slot);
43-
bool NDSSlotChecksumValid(const uint8_t *Buffer, const uint8_t Slot, const uint16_t CHKS);
44-
45-
uint16_t CalcNDSSlotHeader(const uint8_t *Buffer, const uint8_t Slot);
46-
bool NDSSlotChecksumHeaderValid(const uint8_t *Buffer, const uint8_t Slot, const uint16_t CHKS);
47-
48-
uint16_t CalcNDSSlotShared(const uint8_t *Buffer, const uint8_t Slot);
49-
bool NDSSlotChecksumSharedValid(const uint8_t *Buffer, const uint8_t Slot, const uint16_t CHKS);
34+
uint16_t Calc(const uint8_t *Buffer, const uint16_t StartIndex, const uint16_t EndIndex, const std::vector<int> &SkipOffs = { });
5035
};
5136

5237
#endif

include/shared/SAVUtils.hpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ namespace SAVUtils {
4747

4848
const std::string ReadString(const uint8_t *Buffer, const uint32_t Offset, const uint32_t Length);
4949
void WriteString(uint8_t *Buffer, const uint32_t Offset, const uint32_t Length, const std::string &Str);
50+
uint8_t ReadBits(const uint8_t *Buffer, const uint32_t Offs, const bool First);
51+
void WriteBits(uint8_t *Buffer, const uint32_t Offs, const bool First, const uint8_t Data);
5052
};
5153

5254

@@ -60,7 +62,7 @@ namespace GBASAVUtils {
6062
const uint32_t Offs: The Offset from where to read.
6163
*/
6264
template <typename T>
63-
T Read(const uint32_t Offs) {
65+
const T Read(const uint32_t Offs) {
6466
if (!GBASAVUtils::SAV || !GBASAVUtils::SAV->GetValid()) return 0; // Return 0, if nullptr OR invalid.
6567

6668
return *reinterpret_cast<T *>(GBASAVUtils::SAV->GetData() + Offs);
@@ -79,6 +81,9 @@ namespace GBASAVUtils {
7981
*reinterpret_cast<T *>(GBASAVUtils::SAV->GetData() + Offs) = Data;
8082
if (!GBASAVUtils::SAV->GetChangesMade()) GBASAVUtils::SAV->SetChangesMade(true);
8183
};
84+
85+
uint8_t ReadBits(const uint32_t Offs, const bool First = true);
86+
void WriteBits(const uint32_t Offs, const bool First = true, const uint8_t Data = 0x0);
8287
};
8388

8489
/* SAVUtils for NDS. */
@@ -91,7 +96,7 @@ namespace NDSSAVUtils {
9196
const uint32_t Offs: The Offset from where to read.
9297
*/
9398
template <typename T>
94-
T Read(const uint32_t Offs) {
99+
const T Read(const uint32_t Offs) {
95100
if (!NDSSAVUtils::SAV || !NDSSAVUtils::SAV->GetValid()) return 0; // Return 0, if nullptr OR invalid.
96101

97102
return *reinterpret_cast<T *>(NDSSAVUtils::SAV->GetData() + Offs);
@@ -110,6 +115,10 @@ namespace NDSSAVUtils {
110115
*reinterpret_cast<T *>(NDSSAVUtils::SAV->GetData() + Offs) = Data;
111116
if (!NDSSAVUtils::SAV->GetChangesMade()) NDSSAVUtils::SAV->SetChangesMade(true);
112117
};
118+
119+
120+
uint8_t ReadBits(const uint32_t Offs, const bool First = true);
121+
void WriteBits(const uint32_t Offs, const bool First = true, const uint8_t Data = 0x0);
113122
};
114123

115124
#endif

source/gba/GBASav.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,7 @@ void GBASAV::Finish() {
9090
if (!this->GetValid()) return;
9191

9292
for (uint8_t Slot = 1; Slot < 5; Slot++) {
93-
if (this->SlotExist(Slot)) {
94-
if (!Checksum::GBASlotChecksumValid(this->SAVData.get(), Slot, *reinterpret_cast<uint16_t *>(this->SAVData.get() + (Slot * 0x1000) + 0xFFE))) {
95-
*reinterpret_cast<uint16_t *>(this->SAVData.get() + (Slot * 0x1000) + 0xFFE) = Checksum::CalcGBASlot(this->SAVData.get(), Slot);
96-
}
97-
}
93+
if (this->SlotExist(Slot)) this->Slot(Slot)->FixChecksum();
9894
}
9995

10096
/* Do the same with the Settings. */

source/gba/GBASettings.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,10 @@ void GBASettings::Language(const GBALanguage V) {
5353

5454
/* Update the Checksum of the GBA Settings. */
5555
void GBASettings::UpdateChecksum() {
56-
if (!Checksum::GBASettingsValid(GBASAVUtils::SAV->GetData(), GBASAVUtils::Read<uint16_t>(0xE))) { // Update if not valid.
57-
GBASAVUtils::Write<uint16_t>(0xE, Checksum::CalcGBASettings(GBASAVUtils::SAV->GetData()));
56+
const uint16_t CurCHKS = GBASAVUtils::Read<uint16_t>(0xE);
57+
const uint16_t Calced = Checksum::Calc(GBASAVUtils::SAV->GetData(), 0x0, (0x18 / 2), { (0xE / 2) });
58+
59+
if (Calced != CurCHKS) { // If the calced result is NOT the current checksum.
60+
GBASAVUtils::Write<uint16_t>(0xE, Calced);
5861
}
5962
};

source/gba/GBASlot.cpp

Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,74 @@ void GBASlot::Ratings(const uint16_t V) { GBASAVUtils::Write<uint16_t>(this->Off
5353
std::string GBASlot::Name() const { return SAVUtils::ReadString(GBASAVUtils::SAV->GetData(), this->Offs + 0xD, 0x8); };
5454
void GBASlot::Name(const std::string &V) { SAVUtils::WriteString(GBASAVUtils::SAV->GetData(), this->Offs + 0xD, 0x8, V); };
5555

56+
/* Get and Set Hairstyle. */
57+
uint8_t GBASlot::Hairstyle() const { return GBASAVUtils::ReadBits(this->Offs + 0x1D, false) / 2; };
58+
void GBASlot::Hairstyle(const uint8_t V) {
59+
if (V > 7) return;
60+
61+
GBASAVUtils::WriteBits(this->Offs + 0x1D, false, (V * 2) + (this->Shirtcolor3() > 15 ? 0x1 : 0x0));
62+
};
63+
64+
/* Get and Set third Shirtcolor (Long Sleeves). */
65+
uint8_t GBASlot::Shirtcolor3() const { return ((GBASAVUtils::ReadBits(this->Offs + 0x1D, false) % 2 == 1) ? 16 : 0) + GBASAVUtils::ReadBits(this->Offs + 0x1D, true); };
66+
void GBASlot::Shirtcolor3(const uint8_t V) {
67+
GBASAVUtils::WriteBits(this->Offs + 0x1D, true, ((V > 15) ? V - 16 : V));
68+
GBASAVUtils::WriteBits(this->Offs + 0x1D, false, (this->Hairstyle() * 2) + (V > 15 ? 0x1 : 0x0)); // Refresh Hairstyle as well.
69+
};
70+
71+
/* Get and Set Tan / Skin color. */
72+
uint8_t GBASlot::Tan() const { return GBASAVUtils::ReadBits(this->Offs + 0x1E, false) / 2; };
73+
void GBASlot::Tan(const uint8_t V) {
74+
if (V > 5) return;
75+
76+
GBASAVUtils::WriteBits(this->Offs + 0x1E, false, (V * 2) + (this->Shirtcolor2() > 15 ? 0x1 : 0x0));
77+
};
78+
79+
/* Get and Set second Shirtcolor (Short Sleeves). */
80+
uint8_t GBASlot::Shirtcolor2() const { return ((GBASAVUtils::ReadBits(this->Offs + 0x1E, false) % 2 == 1) ? 16 : 0) + GBASAVUtils::ReadBits(this->Offs + 0x1E, true); };
81+
void GBASlot::Shirtcolor2(const uint8_t V) {
82+
GBASAVUtils::WriteBits(this->Offs + 0x1E, true, ((V > 15) ? V - 16 : V));
83+
GBASAVUtils::WriteBits(this->Offs + 0x1E, false, (GBASAVUtils::ReadBits(this->Offs + 0x1E, false) * 2) + (V > 15 ? 0x1 : 0x0)); // Refresh Tan as well.
84+
};
85+
86+
/* Get and Set Haircolor. */
87+
uint8_t GBASlot::Haircolor() const { return GBASAVUtils::ReadBits(this->Offs + 0x1F, false); };
88+
void GBASlot::Haircolor(const uint8_t V) { GBASAVUtils::WriteBits(this->Offs + 0x1F, false, V); };
89+
90+
/* Get the Hatcolor. NOTE: Is also shoe color. */
91+
uint8_t GBASlot::Hatcolor() const { return GBASAVUtils::ReadBits(this->Offs + 0x1F, true); };
92+
void GBASlot::Hatcolor(const uint8_t V) { GBASAVUtils::WriteBits(this->Offs + 0x1F, true, V); };
93+
94+
/* Get and Set Shirt Type. */
95+
uint8_t GBASlot::Shirt() const { return GBASAVUtils::ReadBits(this->Offs + 0x20, false) / 2; };
96+
void GBASlot::Shirt(const uint8_t V) {
97+
if (V > 5) return;
98+
99+
GBASAVUtils::WriteBits(this->Offs + 0x20, false, (V * 2) + (this->Shirtcolor1() > 15 ? 0x1 : 0x0));
100+
};
101+
102+
/* Get and Set first Shirtcolor (Body). */
103+
uint8_t GBASlot::Shirtcolor1() const { return ((GBASAVUtils::ReadBits(this->Offs + 0x20, false) % 2 == 1) ? 16 : 0) + GBASAVUtils::ReadBits(this->Offs + 0x20, true); };
104+
void GBASlot::Shirtcolor1(const uint8_t V) {
105+
GBASAVUtils::WriteBits(this->Offs + 0x20, true, ((V > 15) ? V - 16 : V));
106+
GBASAVUtils::WriteBits(this->Offs + 0x20, false, (GBASAVUtils::ReadBits(this->Offs + 0x20, false) * 2) + (V > 15 ? 0x1 : 0x0)); // Refresh Shirt as well.
107+
};
108+
109+
/* Get and Set Pants. */
110+
uint8_t GBASlot::Pants() const { return GBASAVUtils::ReadBits(this->Offs + 0x21, false) / 2; };
111+
void GBASlot::Pants(const uint8_t V) {
112+
if (V > 1) return;
113+
114+
GBASAVUtils::WriteBits(this->Offs + 0x21, false, (V * 2) + (this->Pantscolor() > 15 ? 0x1 : 0x0));
115+
};
116+
117+
/* Get and Set Pantscolor. */
118+
uint8_t GBASlot::Pantscolor() const { return ((GBASAVUtils::ReadBits(this->Offs + 0x21, false) % 2 == 1) ? 16 : 0) + GBASAVUtils::ReadBits(this->Offs + 0x21, true); };
119+
void GBASlot::Pantscolor(const uint8_t V) {
120+
GBASAVUtils::WriteBits(this->Offs + 0x21, true, ((V > 15) ? V - 16 : V));
121+
GBASAVUtils::WriteBits(this->Offs + 0x21, false, (this->Pants() * 2) + (V > 15 ? 0x1 : 0x0)); // Refresh Pants as well.
122+
};
123+
56124
/* Get and Set the Confidence Skill Points. */
57125
uint8_t GBASlot::Confidence() const { return GBASAVUtils::Read<uint8_t>(this->Offs + 0x22); };
58126
void GBASlot::Confidence(const uint8_t V) { GBASAVUtils::Write<uint8_t>(this->Offs + 0x22, std::min<uint8_t>(5, V)); };
@@ -81,6 +149,10 @@ void GBASlot::Intellect(const uint8_t V) { GBASAVUtils::Write<uint8_t>(this->Off
81149
uint8_t GBASlot::Sanity() const { return GBASAVUtils::Read<uint8_t>(this->Offs + 0x32); };
82150
void GBASlot::Sanity(const uint8_t V) { GBASAVUtils::Write<uint8_t>(this->Offs + 0x32, std::min<uint8_t>(100, V)); };
83151

152+
/* Get and Set the Aspiration. */
153+
uint8_t GBASlot::Aspiration() const { return GBASAVUtils::Read<uint8_t>(this->Offs + 0x4B); };
154+
void GBASlot::Aspiration(const uint8_t V) { GBASAVUtils::Write<uint8_t>(this->Offs + 0x4B, std::min<uint8_t>(2, V)); };
155+
84156
/* Return some Item Groups of 6 Items each group. */
85157
std::unique_ptr<GBAItem> GBASlot::PawnShop() const { return std::make_unique<GBAItem>(this->Offs + 0x4C); };
86158
std::unique_ptr<GBAItem> GBASlot::Saloon() const { return std::make_unique<GBAItem>(this->Offs + 0x5F); };
@@ -171,8 +243,12 @@ std::unique_ptr<GBASocialMove> GBASlot::SocialMove(const uint8_t Move) const {
171243
bool GBASlot::FixChecksum() {
172244
if (this->Slot < 1 || this->Slot > 4) return false;
173245

174-
if (!Checksum::GBASlotChecksumValid(GBASAVUtils::SAV->GetData(), this->Slot, GBASAVUtils::Read<uint16_t>((this->Slot * 0x1000) + 0xFFE))) {
175-
GBASAVUtils::Write<uint16_t>((this->Slot * 0x1000) + 0xFFE, Checksum::CalcGBASlot(GBASAVUtils::SAV->GetData(), this->Slot));
246+
const uint16_t CurCHKS = GBASAVUtils::Read<uint16_t>(this->Offs + 0xFFE);
247+
const uint16_t Calced = Checksum::Calc(GBASAVUtils::SAV->GetData(), (this->Offs / 2), ((this->Offs + 0xFFE) / 2));
248+
249+
250+
if (Calced != CurCHKS) { // If the calced result is NOT the current checksum.
251+
GBASAVUtils::Write<uint16_t>(this->Offs + 0xFFE, Calced);
176252
return true;
177253
}
178254

0 commit comments

Comments
 (0)