Skip to content

Commit 32f2bfa

Browse files
authored
use rune mgr to save/restore runes (#21)
1 parent 928945d commit 32f2bfa

9 files changed

+79
-34
lines changed

CHANGELOG.md

-29
This file was deleted.

Megaton.toml

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ includes = [
1818
"libs/nnheaders/include",
1919
]
2020
ldscripts = [
21+
"symbols.ld",
2122
"libs/botw-symbols/ld/ld160.ld",
2223
"libs/botw-symbols/ld/toolkit160.ld",
2324
]

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ The following will always be enabled, and you cannot turn them off:
111111
- Current Stamina
112112
- Position (Havok Position and Main Position Matrix)
113113
- Camera Matrix
114+
- Selected Rune
114115

115116
Additionally, the following will happen when you restore, regardless of the setting:
116117
- Runes will finish cooldown

src/core/state.cpp

+23
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "core/state.hpp"
1414
#include "core/version.hpp"
1515
#include "impl/raw_ptr.hpp"
16+
#include "impl/rune.hpp"
1617

1718
namespace botw::savs {
1819

@@ -53,6 +54,14 @@ void State::read_from_game(Reporter& r, const StateConfig& config) {
5354
raw_ptr::camera_pan_matrix().get_array(m_camera_pan_matrix, 12));
5455
r.report("CamZoom", raw_ptr::camera_zoom().get(&m_camera_zoom));
5556
r.report("CamTilt", raw_ptr::camera_tilt().get(&m_camera_tilt));
57+
58+
auto rune_mgr = RuneMgr::get_instance();
59+
if (rune_mgr == nullptr) {
60+
r.report("RuneMgr", false);
61+
} else {
62+
m_rune = rune_mgr->get_current();
63+
}
64+
5665
if (!r.has_error()) {
5766
m_stored_essentials = true;
5867
}
@@ -135,6 +144,14 @@ void State::write_to_game(Reporter& r, const StateConfig& config,
135144
r.report("CamZoom", raw_ptr::camera_zoom().set(m_camera_zoom));
136145
r.report("CamTilt", raw_ptr::camera_tilt().set(m_camera_tilt));
137146

147+
// selected rune
148+
auto rune_mgr = RuneMgr::get_instance();
149+
if (rune_mgr == nullptr) {
150+
r.report("RuneMgr", false);
151+
} else {
152+
rune_mgr->set_current(m_rune);
153+
}
154+
138155
// extras
139156
r.report("RdBombCD", raw_ptr::round_bomb_cooldown().set(360.0F));
140157
r.report("SqBombCD", raw_ptr::square_bomb_cooldown().set(360.0F));
@@ -271,6 +288,10 @@ StateFileResult State::read_from_file(io::DataReader& r) {
271288
m_pmdm_state.read_from_file(r);
272289
}
273290

291+
if (version >= Version::v8) {
292+
r.read_integer(&m_rune);
293+
}
294+
274295
if (!r.is_successful()) {
275296
clear();
276297
return StateFileResult::IOError;
@@ -325,6 +346,8 @@ StateFileResult State::write_to_file(io::DataWriter& w) const {
325346
w.write_integer(_named(m_num_inventory_count_offset));
326347
m_pmdm_state.write_to_file(w);
327348

349+
w.write_integer(_named(m_rune));
350+
328351
if (!w.is_successful()) {
329352
return StateFileResult::IOError;
330353
}

src/core/state.hpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,11 @@ class State {
6262
float m_camera_pan_matrix[12];
6363
float m_camera_zoom;
6464
float m_camera_tilt;
65+
u32 m_rune;
6566
/* Extra stuff always restored:
6667
* - Rune cooldown
6768
* - Delete bombs
6869
* - TODO: fall damage
69-
* - TODO: selected rune
70-
*
7170
*/
7271

7372
// timers

src/core/version.hpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ namespace botw::savs {
44
enum Version {
55
vLegacy = 4, // no longer supported
66
v5 = 5,
7-
v6 = 6,
8-
v7 = 7,
9-
vLatest = v7
7+
v6 = 6, // inventory (PMDM)
8+
v7 = 7, // speedometer
9+
v8 = 8, // rune
10+
vLatest = v8
1011
};
1112
}

src/impl/rune.cpp

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#include <toolkit/scoped_lock.hpp>
2+
3+
#include "rune.hpp"
4+
5+
extern "C" {
6+
7+
// 0x02C9A668
8+
extern botw::savs::RuneMgr* botw_savs__RuneMgr;
9+
}
10+
11+
namespace botw::savs {
12+
13+
RuneMgr* RuneMgr::get_instance() { return botw_savs__RuneMgr; }
14+
15+
void RuneMgr::set_current(u32 rune_type) {
16+
toolkit::ScopedLock lock(&item_cs.mCriticalSectionInner);
17+
this->rune_type = rune_type;
18+
}
19+
20+
u32 RuneMgr::get_current() {
21+
toolkit::ScopedLock lock(&item_cs.mCriticalSectionInner);
22+
return this->rune_type;
23+
}
24+
25+
} // namespace botw::savs

src/impl/rune.hpp

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#pragma once
2+
3+
#include <thread/seadCriticalSection.h>
4+
5+
// TODO: upstream to decomp
6+
//
7+
namespace botw::savs {
8+
9+
class RuneMgr {
10+
public:
11+
static RuneMgr* get_instance();
12+
13+
void set_current(u32 rune_type);
14+
u32 get_current();
15+
16+
char _x0[0x200];
17+
sead::CriticalSection item_cs;
18+
u32 rune_type;
19+
};
20+
21+
static_assert(offsetof(RuneMgr, rune_type) == 0x240, "");
22+
23+
} // namespace botw::savs

symbols.ld

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
PROVIDE_HIDDEN(botw_savs__RuneMgr = 0x02C9A668 - 0x3483000);

0 commit comments

Comments
 (0)