-
-
Save aixxe/a9d9390635978685ae758a7e2b065872 to your computer and use it in GitHub Desktop.
Score hook library headers
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
/* | |
* bm2dx.exe | |
* | |
* Size: 8677216 bytes (8473 KiB) | |
* SHA256: C4C5B65D0F0A9824C70A23A5F1BD8B83B6A81B3D9B6BADFF52B41FEA62DD7285 | |
*/ | |
// Offsets | |
constexpr std::uintptr_t game_state_addr = 0x2619B94; | |
constexpr std::uintptr_t judgement_addr = 0x28967C4; | |
constexpr std::uintptr_t pacemaker_addr = 0x112160; | |
constexpr std::uintptr_t player_name_addr = 0x1092105; | |
// Constants | |
constexpr auto PLAYER_P1 = 0; | |
constexpr auto PLAYER_P2 = 1; | |
constexpr auto PLAYSTYLE_SP = 0; | |
constexpr auto PLAYSTYLE_DP = 1; | |
constexpr auto DIFFICULTY_NORMAL = 0; | |
constexpr auto DIFFICULTY_HYPER = 1; | |
constexpr auto DIFFICULTY_ANOTHER = 2; | |
// String tables | |
const char* DJ_LEVEL[] = { | |
"level_s_aaa", | |
"level_s_aa", | |
"level_s_a", | |
"level_s_b", | |
"level_s_c", | |
"level_s_d", | |
"level_s_e", | |
"level_s_f" | |
}; | |
const char* PACEMAKER_TYPE[] = { | |
"sg_fno", | |
"sg_monly", | |
"sg_riva1", | |
"sg_riva2", | |
"sg_riva3", | |
"sg_riva4", | |
"sg_riva5", | |
"sg_riva_top", | |
"sg_riva_ave", | |
"sg_altop", | |
"sg_alave", | |
"sg_lotop", | |
"sg_loave", | |
"sg_dantp", | |
"sg_danav", | |
"sg_ghost", | |
"sg_pacemaker_aaa", | |
"sg_pacemaker_aa", | |
"sg_pacemaker_a", | |
"sg_pacemaker" | |
}; | |
const char* CLEAR_TYPE[] = { | |
"clear_noplay", | |
"clear_failed", | |
"clear_assist", | |
"clear_easy", | |
"clear_clear", | |
"clear_hard", | |
"clear_ex", | |
"clear_fullcombo" | |
}; | |
// Classes | |
class StageResultDrawFrame { | |
private: | |
virtual ~StageResultDrawFrame() = 0; | |
public: | |
struct frame_player_t { | |
int32_t best_clear_type; //0x0004 | |
int32_t current_clear_type; //0x0008 | |
int32_t best_dj_level; //0x000C | |
int32_t current_dj_level; //0x0010 | |
int32_t best_ex_score; //0x0014 | |
int32_t current_ex_score; //0x0018 | |
int32_t best_miss_count; //0x001C | |
int32_t current_miss_count; //0x0020 | |
int8_t show_best_clear_type; //0x0024 | |
int8_t show_current_clear_type; //0x0025 | |
int8_t show_best_dj_level; //0x0026 | |
int8_t show_current_dj_level; //0x0027 | |
int8_t show_best_ex_score; //0x0028 | |
int8_t show_current_ex_score; //0x0029 | |
int8_t show_best_miss_count; //0x002A | |
int8_t show_current_miss_count; //0x002B | |
int32_t highlighted_clear_type; //0x002C | |
int32_t highlighted_dj_level; //0x0030 | |
int32_t highlighted_ex_score; //0x0034 | |
int32_t highlighted_miss_count; //0x0038 | |
} p1, p2; | |
}; | |
// Structures | |
struct music_data { | |
char title[64]; //0x0000 | |
char title_ascii[64]; //0x0040 | |
char genre[64]; //0x0080 | |
char artist[64]; //0x00C0 | |
char pad_0100[32]; //0x0100 | |
int8_t sp_normal_rating; //0x0120 | |
int8_t sp_hyper_rating; //0x0121 | |
int8_t sp_another_rating; //0x0122 | |
int8_t dp_normal_rating; //0x0123 | |
int8_t dp_hyper_rating; //0x0124 | |
int8_t dp_another_rating; //0x0125 | |
char pad_0126[2]; //0x0126 | |
int32_t sp_normal_bpm_max; //0x0128 | |
int32_t sp_normal_bpm_min; //0x012C | |
int32_t sp_hyper_bpm_max; //0x0130 | |
int32_t sp_hyper_bpm_min; //0x0134 | |
int32_t sp_another_bpm_max; //0x0138 | |
int32_t sp_another_bpm_min; //0x013C | |
int32_t dp_normal_bpm_max; //0x0140 | |
int32_t dp_normal_bpm_min; //0x0144 | |
int32_t dp_hyper_bpm_max; //0x0148 | |
int32_t dp_hyper_bpm_min; //0x014C | |
int32_t dp_another_bpm_max; //0x0150 | |
int32_t dp_another_bpm_min; //0x0154 | |
char pad_0158[16]; //0x0158 | |
uint32_t sp_normal_notes; //0x0168 | |
uint32_t sp_hyper_notes; //0x016C | |
uint32_t sp_another_notes; //0x0170 | |
uint32_t dp_normal_notes; //0x0174 | |
uint32_t dp_hyper_notes; //0x0178 | |
uint32_t dp_another_notes; //0x017C | |
char pad_0180[72]; //0x0180 | |
int32_t entry_id; //0x01C8 | |
char pad_01CC[340]; //0x01CC | |
}; | |
struct state_t { | |
uint32_t play_style; | |
char pad_0004[4]; | |
uint32_t p1_difficulty; | |
uint32_t p2_difficulty; | |
uint32_t p1_active; | |
uint32_t p2_active; | |
music_data* music; | |
}; | |
struct pacemaker_t { | |
int32_t type; | |
int32_t score; | |
char name[256] = {'\0'}; | |
}; | |
struct judgement_t { | |
int32_t p1_pgreat; | |
int32_t p1_great; | |
int32_t p1_good; | |
int32_t p1_bad; | |
int32_t p1_poor; | |
int32_t p2_pgreat; | |
int32_t p2_great; | |
int32_t p2_good; | |
int32_t p2_bad; | |
int32_t p2_poor; | |
int32_t p1_combo_break; | |
int32_t p2_combo_break; | |
int32_t p1_fast; | |
int32_t p2_fast; | |
int32_t p1_slow; | |
int32_t p2_slow; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
// General helper function for getting absolute addresses from relative instructions. | |
template <typename T = void*> inline T GetAbsoluteAddress(std::uintptr_t addr, std::size_t offset = 0, std::size_t length = 5) { | |
return reinterpret_cast<T>(addr + length + *reinterpret_cast<std::uint32_t*>(addr + 1) + offset); | |
} | |
extern state_t* state; | |
extern judgement_t* judgement; | |
namespace bm2dx { | |
struct chart_t { | |
int8_t rating; | |
int32_t bpm_min; | |
int32_t bpm_max; | |
uint32_t notes; | |
}; | |
struct judgement_player_t { | |
int32_t pgreat; | |
int32_t great; | |
int32_t good; | |
int32_t bad; | |
int32_t poor; | |
int32_t combo_break; | |
int32_t fast; | |
int32_t slow; | |
}; | |
const judgement_player_t get_judgement() { | |
if (state->play_style == PLAYSTYLE_DP) { | |
return { | |
judgement->p1_pgreat + judgement->p2_pgreat, | |
judgement->p1_great + judgement->p2_great, | |
judgement->p1_good + judgement->p2_good, | |
judgement->p1_bad + judgement->p2_bad, | |
judgement->p1_poor + judgement->p2_poor, | |
judgement->p1_combo_break + judgement->p2_combo_break, | |
judgement->p1_fast + judgement->p2_fast, | |
judgement->p1_slow + judgement->p2_slow, | |
}; | |
} | |
return { | |
state->p1_active ? judgement->p1_pgreat: judgement->p2_pgreat, | |
state->p1_active ? judgement->p1_great: judgement->p2_great, | |
state->p1_active ? judgement->p1_good: judgement->p2_good, | |
state->p1_active ? judgement->p1_bad: judgement->p2_bad, | |
state->p1_active ? judgement->p1_poor: judgement->p2_poor, | |
state->p1_active ? judgement->p1_combo_break: judgement->p2_combo_break, | |
state->p1_active ? judgement->p1_fast: judgement->p2_fast, | |
state->p1_active ? judgement->p1_slow: judgement->p2_slow, | |
}; | |
} | |
// Single play charts. | |
const chart_t get_spn_chart(music_data* music) { | |
return { | |
music->sp_normal_rating, | |
music->sp_normal_bpm_min, | |
music->sp_normal_bpm_max, | |
music->sp_normal_notes | |
}; | |
} | |
const chart_t get_sph_chart(music_data* music) { | |
return { | |
music->sp_hyper_rating, | |
music->sp_hyper_bpm_min, | |
music->sp_hyper_bpm_max, | |
music->sp_hyper_notes | |
}; | |
} | |
const chart_t get_spa_chart(music_data* music) { | |
return { | |
music->sp_another_rating, | |
music->sp_another_bpm_min, | |
music->sp_another_bpm_max, | |
music->sp_another_notes | |
}; | |
} | |
// Double play charts. | |
const chart_t get_dpn_chart(music_data* music) { | |
return { | |
music->dp_normal_rating, | |
music->dp_normal_bpm_min, | |
music->dp_normal_bpm_max, | |
music->dp_normal_notes | |
}; | |
} | |
const chart_t get_dph_chart(music_data* music) { | |
return { | |
music->dp_hyper_rating, | |
music->dp_hyper_bpm_min, | |
music->dp_hyper_bpm_max, | |
music->dp_hyper_notes | |
}; | |
} | |
const chart_t get_dpa_chart(music_data* music) { | |
return { | |
music->dp_another_rating, | |
music->dp_another_bpm_min, | |
music->dp_another_bpm_max, | |
music->dp_another_notes | |
}; | |
} | |
const chart_t get_chart() { | |
auto difficulty = state->p1_active ? state->p1_difficulty: state->p2_difficulty; | |
switch (difficulty) { | |
case DIFFICULTY_NORMAL: | |
return (state->play_style == PLAYSTYLE_SP) ? | |
get_spn_chart(state->music): | |
get_dpn_chart(state->music); | |
case DIFFICULTY_HYPER: | |
return (state->play_style == PLAYSTYLE_SP) ? | |
get_sph_chart(state->music): | |
get_dph_chart(state->music); | |
case DIFFICULTY_ANOTHER: | |
default: | |
return (state->play_style == PLAYSTYLE_SP) ? | |
get_spa_chart(state->music): | |
get_dpa_chart(state->music); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment