Add CWeaponMgr

This commit is contained in:
Henrique Gemignani Passos Lima 2022-11-10 04:06:24 +02:00
parent 70e69ea33b
commit 28983db847
No known key found for this signature in database
GPG Key ID: E224F951761145F8
7 changed files with 126 additions and 8 deletions

View File

@ -323,7 +323,7 @@ lbl_800C20C4:
/* 800C20DC 000BF03C 38 05 00 01 */ addi r0, r5, 1
/* 800C20E0 000BF040 7C 08 39 2E */ stwx r0, r8, r7
/* 800C20E4 000BF044 80 A4 00 10 */ lwz r5, 0x10(r4)
/* 800C20E8 000BF048 48 00 02 3D */ bl sub_800c2324
/* 800C20E8 000BF048 48 00 02 3D */ bl "insert_into__Q24rstl215red_black_tree<9TUniqueId,Q24rstl47pair<9TUniqueId,Q24rstl21reserved_vector<i,15>>,0,Q24rstl67select1st<Q24rstl47pair<9TUniqueId,Q24rstl21reserved_vector<i,15>>>,Q24rstl16less<9TUniqueId>,Q24rstl17rmemory_allocator>FPQ34rstl215red_black_tree<9TUniqueId,Q24rstl47pair<9TUniqueId,Q24rstl21reserved_vector<i,15>>,0,Q24rstl67select1st<Q24rstl47pair<9TUniqueId,Q24rstl21reserved_vector<i,15>>>,Q24rstl16less<9TUniqueId>,Q24rstl17rmemory_allocator>4nodeRCQ24rstl47pair<9TUniqueId,Q24rstl21reserved_vector<i,15>>"
/* 800C20EC 000BF04C 28 1F 00 00 */ cmplwi r31, 0
/* 800C20F0 000BF050 41 82 00 70 */ beq lbl_800C2160
/* 800C20F4 000BF054 80 A1 00 64 */ lwz r5, 0x64(r1)
@ -497,8 +497,8 @@ __dl__FPv:
/* 800C231C 000BF27C 38 21 00 10 */ addi r1, r1, 0x10
/* 800C2320 000BF280 4E 80 00 20 */ blr
.global sub_800c2324
sub_800c2324:
.global "insert_into__Q24rstl215red_black_tree<9TUniqueId,Q24rstl47pair<9TUniqueId,Q24rstl21reserved_vector<i,15>>,0,Q24rstl67select1st<Q24rstl47pair<9TUniqueId,Q24rstl21reserved_vector<i,15>>>,Q24rstl16less<9TUniqueId>,Q24rstl17rmemory_allocator>FPQ34rstl215red_black_tree<9TUniqueId,Q24rstl47pair<9TUniqueId,Q24rstl21reserved_vector<i,15>>,0,Q24rstl67select1st<Q24rstl47pair<9TUniqueId,Q24rstl21reserved_vector<i,15>>>,Q24rstl16less<9TUniqueId>,Q24rstl17rmemory_allocator>4nodeRCQ24rstl47pair<9TUniqueId,Q24rstl21reserved_vector<i,15>>"
"insert_into__Q24rstl215red_black_tree<9TUniqueId,Q24rstl47pair<9TUniqueId,Q24rstl21reserved_vector<i,15>>,0,Q24rstl67select1st<Q24rstl47pair<9TUniqueId,Q24rstl21reserved_vector<i,15>>>,Q24rstl16less<9TUniqueId>,Q24rstl17rmemory_allocator>FPQ34rstl215red_black_tree<9TUniqueId,Q24rstl47pair<9TUniqueId,Q24rstl21reserved_vector<i,15>>,0,Q24rstl67select1st<Q24rstl47pair<9TUniqueId,Q24rstl21reserved_vector<i,15>>>,Q24rstl16less<9TUniqueId>,Q24rstl17rmemory_allocator>4nodeRCQ24rstl47pair<9TUniqueId,Q24rstl21reserved_vector<i,15>>":
/* 800C2324 000BF284 94 21 FF E0 */ stwu r1, -0x20(r1)
/* 800C2328 000BF288 7C 08 02 A6 */ mflr r0
/* 800C232C 000BF28C 28 05 00 00 */ cmplwi r5, 0

View File

@ -120,7 +120,7 @@ LIBS = [
"MetroidPrime/CParticleDatabase",
"MetroidPrime/Tweaks/CTweakGunRes",
"MetroidPrime/CTargetReticles",
"MetroidPrime/CWeaponMgr",
["MetroidPrime/CWeaponMgr", False],
["MetroidPrime/ScriptObjects/CScriptPickup", True],
["MetroidPrime/CDamageInfo", False],
["MetroidPrime/CMemoryDrawEnum", True],

View File

@ -4,13 +4,38 @@
#include "types.h"
#include "MetroidPrime/TGameTypes.hpp"
#include "MetroidPrime/Weapons/WeaponTypes.hpp"
#include "rstl/map.hpp"
#include "rstl/reserved_vector.hpp"
class CWeaponMgr {
public:
typedef rstl::reserved_vector< int, 15 > Vec;
CWeaponMgr();
void Remove(TUniqueId);
void IncrCount(TUniqueId, EWeaponType);
void DecrCount(TUniqueId, EWeaponType);
int GetNumActive(TUniqueId, EWeaponType) const;
void Add(TUniqueId uid, EWeaponType type) {
rstl::pair< TUniqueId, Vec > newIndex(uid, Vec(0));
newIndex.second[type] += 1;
x0_weapons.insert(newIndex);
}
Vec* GetIndex(TUniqueId uid) const {
rstl::map< TUniqueId, Vec >::const_iterator iter = x0_weapons.find(uid);
if (iter != x0_weapons.end()) {
return const_cast<Vec*>(&iter->second);
}
return nullptr;
}
private:
rstl::map< TUniqueId, rstl::reserved_vector< int, 15 > > x0_weapons;
rstl::map< TUniqueId, Vec > x0_weapons;
};
CHECK_SIZEOF(CWeaponMgr, 0x14);

View File

@ -53,7 +53,7 @@ struct TUniqueId {
bool operator==(const TUniqueId& other) const { return value == other.value; }
bool operator!=(const TUniqueId& other) const { return value != other.value; }
bool operator<(const TUniqueId& other) const; // TODO
bool operator<(const TUniqueId& other) const { return value < other.value; }
private:
};

View File

@ -18,16 +18,20 @@ private:
typedef red_black_tree< K, value_type, 0, select1st< value_type >, Cmp, Alloc > rep_type;
public:
// typedef typename rep_type::iterator iterator;
typedef typename rep_type::iterator iterator;
typedef typename rep_type::const_iterator const_iterator;
void insert(const value_type& item) { inner.insert(item); }
iterator insert(const value_type& item) { return inner.insert(item); }
const_iterator begin() const { return inner.begin(); }
const_iterator end() const { return inner.end(); }
iterator find(const K& key) { return inner.find(key); }
const_iterator find(const K& key) const { return inner.find(key); }
void erase(iterator it) { inner.erase(it); }
rep_type& get_inner() { return inner; } // hack for CWeaponMgr inlining depth
private:
rep_type inner;
};

View File

@ -29,6 +29,7 @@ enum node_color {
void rbtree_rebalance(void*, void*);
void* rbtree_traverse_forward(const void*, void*);
void* rbtree_rebalance_for_erase(void* header_void, void* node_void);
template < typename T, typename P, int U, typename S = select1st< P >, typename Cmp = less< T >,
typename Alloc = rmemory_allocator >
@ -45,6 +46,9 @@ private:
: mLeft(left), mRight(right), mParent(parent), mColor(color) {
construct(get_value(), value);
}
~node() {
get_value()->~P();
}
P* get_value() { return reinterpret_cast< P* >(&mValue); }
const P* get_value() const { return reinterpret_cast< const P* >(&mValue); }
@ -106,6 +110,10 @@ public:
};
struct iterator : public const_iterator {
iterator(node* node, const header* header, bool b) : const_iterator(node, header, b) {}
P* operator->() { return mNode->get_value(); }
P* operator*() { return mNode->get_value(); }
node* get_node() { return mNode; }
};
red_black_tree() : x0_(0), x1_(0), x4_count(0) {}
@ -144,6 +152,35 @@ public:
return const_iterator(needle, &x8_header, false);
}
iterator find(const T& key) {
node* n = x8_header.get_root();
node* needle = nullptr;
while (n != nullptr) {
if (!x2_cmp(x3_selector(*n->get_value()), key)) {
needle = n;
n = n->get_left();
} else {
n = n->get_right();
}
}
bool noResult = false;
if (needle == nullptr || x2_cmp(key, x3_selector(*needle->get_value()))) {
noResult = true;
}
if (noResult) {
needle = nullptr;
}
return iterator(needle, &x8_header, false);
}
iterator erase(iterator it) {
node* node = it.get_node();
++it;
free_node(rebalance_for_erase(node));
x4_count--;
return it;
}
void clear() {
node* root = x8_header.get_root();
if (root != nullptr) {
@ -186,6 +223,8 @@ private:
}
void rebalance(node* n) { rbtree_rebalance(&x8_header, n); }
node* rebalance_for_erase(node* n) { return static_cast<node*>(rbtree_rebalance_for_erase(&x8_header, n)); }
};
static bool kUnknownValueNewRoot = true;

View File

@ -0,0 +1,50 @@
#include "MetroidPrime/CWeaponMgr.hpp"
CWeaponMgr::CWeaponMgr() {}
void CWeaponMgr::Remove(TUniqueId uid) {
rstl::map< TUniqueId, Vec >::iterator iter = x0_weapons.find(uid);
if (iter != x0_weapons.end()) {
x0_weapons.get_inner().erase(iter);
}
}
void CWeaponMgr::IncrCount(TUniqueId uid, EWeaponType type) {
Vec* vec = GetIndex(uid);
if (vec == nullptr) {
Add(uid, type);
} else {
(*vec)[type]++;
}
}
void CWeaponMgr::DecrCount(TUniqueId uid, EWeaponType type) {
Vec* vecP = GetIndex(uid);
if (!vecP) {
return;
}
Vec& vec = *vecP;
vec[type]--;
bool found = true;
rstl::reserved_vector< int, 15 >::iterator vit = vec.begin(), end = vec.end();
for (; vit != end; ++vit) {
if (*vit > 0) {
found = false;
break;
}
}
if (found) {
Remove(uid);
}
}
int CWeaponMgr::GetNumActive(TUniqueId uid, EWeaponType type) const {
Vec* vecP = GetIndex(uid);
if (vecP) {
return (*vecP)[type];
} else {
return 0;
}
}