Skip to content

Commit 4fbcfc4

Browse files
committed
bolwing
1 parent dcbb239 commit 4fbcfc4

6 files changed

Lines changed: 187 additions & 164 deletions

File tree

lib/libkiwi/fun/kiwiGameCorruptor.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ void** GetRandomAddr(const void* pBegin, const void* pEnd) {
2323

2424
do {
2525
// Make sure to align the address to 4 bytes
26-
offset = Random().NextU32(size);
26+
offset = RNG.NextU32(size);
2727
offset = RoundUp(offset, 4);
2828
}
2929
// Adjusting for alignment may take us out of the range
@@ -89,7 +89,7 @@ void GameCorruptor::Corrupt() const {
8989

9090
case ECorruptDomain_DolData: {
9191
// 50/50 between .data and .rodata
92-
if (Random().CoinFlip()) {
92+
if (RNG.CoinFlip()) {
9393
CorruptData(GetDolDataStart(), GetDolDataEnd());
9494
} else {
9595
CorruptData(GetDolRodataStart(), GetDolRodataEnd());
@@ -170,11 +170,11 @@ void GameCorruptor::CorruptData(const void* pBegin, const void* pEnd) const {
170170
// Corrupt float
171171
if (PtrUtil::IsFloat(ppAddr)) {
172172
*reinterpret_cast<f32*>(ppAddr) =
173-
Random().NextF32(10000000.0f) * Random().Sign();
173+
RNG.NextF32(10000000.0f) * RNG.Sign();
174174
}
175175
// Corrupt integer
176176
else {
177-
*reinterpret_cast<u32*>(ppAddr) = Random().NextU32();
177+
*reinterpret_cast<u32*>(ppAddr) = RNG.NextU32();
178178
}
179179

180180
i++;

lib/libkiwi/net/kiwiSocketBase.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ bool SocketBase::Bind(SockAddrAny& rAddr) const {
6868
if (rAddr.port == 0) {
6969
// Retry up to 10 times in case the random port is in use
7070
for (int i = 0; i < 10; i++) {
71-
rAddr.port = Random().NextU32(49152, 65535);
71+
rAddr.port = RNG.NextU32(49152, 65535);
7272

7373
if (LibSO::Bind(mHandle, rAddr) == SO_SUCCESS) {
7474
return true;

lib/libkiwi/prim/kiwiSTL.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,24 +72,25 @@ const char* strstr(const char* pStr, const char* pSeq) {
7272
K_ASSERT(pStr != nullptr);
7373

7474
// No sequence/empty sequence
75-
if (pSeq == nullptr || *pSeq == L'\0') {
75+
if (pSeq == nullptr || *pSeq == '\0') {
7676
return pStr;
7777
}
7878

7979
// First character in sequence
8080
char begin = *pSeq;
8181

8282
// Check for sequence
83-
while (*pStr != L'\0') {
83+
while (*pStr != '\0') {
8484
// Matches beginning of sequence
8585
if (*pStr == begin) {
8686
// Backup original pointers
8787
const char* pCheck = pStr;
8888
const char* pExpect = pSeq;
8989

9090
// Look for rest of sequence
91-
while (*++pCheck == *++pExpect) {
92-
;
91+
while (*pCheck == *pExpect && *pExpect != '\0') {
92+
pCheck++;
93+
pExpect++;
9394
}
9495

9596
// Did we hit the end?
@@ -344,12 +345,13 @@ const wchar_t* wcsstr(const wchar_t* pwStr, const wchar_t* pwSeq) {
344345
const wchar_t* pExpect = pwSeq;
345346

346347
// Look for rest of sequence
347-
while (*++pCheck == *++pExpect) {
348-
;
348+
while (*pCheck == *pExpect && *pExpect != L'\0') {
349+
pCheck++;
350+
pExpect++;
349351
}
350352

351353
// Did we hit the end?
352-
if (*pExpect == '\0') {
354+
if (*pExpect == L'\0') {
353355
return pwStr;
354356
}
355357
}

lib/libkiwi/util/kiwiBitUtil.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ template <typename T> T BitUtil<T>::PickRandom(T bits) {
104104
}
105105

106106
// Choice means n'th set bit
107-
u32 choice = 1 + Random().NextU32(max);
107+
u32 choice = 1 + RNG.NextU32(max);
108108

109109
u32 mask = 1 << 0;
110110

src/hooks/Bwl/cosmetics_Bwl.cpp

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
#include <types.h>
2+
3+
#include "core/CosmeticMgr.h"
4+
#include "hooks/trampoline.h"
5+
6+
#include <Pack/RPGraphics.h>
7+
#include <Sports2/Sp2Cmn.h>
8+
#include <nw4r/g3d.h>
9+
10+
#include <libkiwi.h>
11+
12+
namespace AP {
13+
namespace Bwl {
14+
namespace Cosmetic {
15+
16+
/******************************************************************************
17+
*
18+
* Random Bowling Ball Color
19+
*
20+
******************************************************************************/
21+
22+
/**
23+
* @brief Overrides the bowling ball model color based on the randomizer
24+
* settings
25+
*
26+
* @param pModel Ball model
27+
* @param mirror Whether this model is the mirror model
28+
* @param color New ball color
29+
*/
30+
void PatchBwlBallColor(RPGrpModelG3D* pModel, bool mirror, kiwi::Color color) {
31+
ASSERT_PTR(pModel);
32+
33+
/**
34+
* Get access to the model material
35+
*/
36+
nw4r::g3d::ScnMdl* pScnMdl = pModel->GetModelEx()->getScnMdl();
37+
ASSERT_PTR(pScnMdl);
38+
39+
nw4r::g3d::ResMdl resMdl = pScnMdl->GetResMdl();
40+
ASSERT(resMdl.IsValid());
41+
42+
nw4r::g3d::ResMat resMat = resMdl.GetResMat("bwg_ball_mat");
43+
ASSERT(resMat.IsValid());
44+
45+
RPGrpModelMaterial* pMaterial = pModel->GetMaterial(resMat.GetID());
46+
ASSERT_PTR(pMaterial);
47+
48+
nw4r::g3d::ScnMdl::CopiedMatAccess& rMatAccess =
49+
pMaterial->GetCopiedMatAccess();
50+
51+
/**
52+
* Write the required TEV colors
53+
*/
54+
// TEVREG0 holds the ball accent color
55+
pMaterial->SetTevColor(GX_TEVREG0, color.ToS10());
56+
// TEVKREG2 is used for greyscale conversion constants
57+
pMaterial->SetTevKColor(GX_KCOLOR2, kiwi::Color(85, 150, 29, 0));
58+
59+
/**
60+
* Prepare the material for the new shader
61+
*/
62+
nw4r::g3d::ResGenMode genMode = rMatAccess.GetResGenMode(false);
63+
ASSERT(genMode.IsValid());
64+
{
65+
// The new shader will have 7 stages
66+
genMode.GXSetNumTevStages(7);
67+
}
68+
genMode.EndEdit();
69+
70+
/**
71+
* Write the TEV shader fragments
72+
*/
73+
nw4r::g3d::ResTev tev = rMatAccess.GetResTev(false);
74+
ASSERT(tev.IsValid());
75+
{
76+
/**
77+
* Ball texture color is converted to greyscale,
78+
* then blended (Addition) with the accent color in TEVREG0
79+
*/
80+
static const u32 ballShader[] = {
81+
0x61FE0000, 0x0F61F600, 0x000461FE, 0x00000F61, 0xF700000E,
82+
0x61FE0000, 0x0F61F800, 0x000061FE, 0x00000F61, 0xF900000C,
83+
0x61FE0000, 0x0F61FA00, 0x000561FE, 0x00000F61, 0xFB00000D,
84+
0x61FE0000, 0x0F61FC00, 0x000A61FE, 0x00000F61, 0xFD00000E,
85+
0x6127FFFF, 0xFF000000, 0x00000000, 0x00000000, 0x61FEFFFF,
86+
0xF061F6E5, 0xB9206128, 0x3C03C061, 0xC088FE8F, 0x61C288FE,
87+
0x8461C108, 0xFFF461C3, 0x08FFF861, 0x10000000, 0x61110000,
88+
0x00000000, 0x61FEFFFF, 0xF061F7E0, 0x39A06129, 0x3BF3C061,
89+
0xC408FE84, 0x61C6002C, 0x0261C508, 0xFFFC61C7, 0x08FFF061,
90+
0x12000000, 0x61130000, 0x00000000, 0x61FEFFFF, 0xF061F8FF,
91+
0xFFF0612A, 0x3C904061, 0xC808F0AF, 0x61CA088F, 0xE061C908,
92+
0xF37061CB, 0x089F0061, 0x14000000, 0x61150000, 0x00000000,
93+
0x61FEFFFF, 0xF061F900, 0x38C0612B, 0x3BF3D261, 0xCC08F80F,
94+
0x00000000, 0x0061CD08, 0xFFE00000, 0x00000061, 0x16000000};
95+
96+
std::memcpy(&tev.ref().dl, ballShader, sizeof(ballShader));
97+
tev.SetNumTevStages(7);
98+
}
99+
tev.EndEdit();
100+
}
101+
102+
/**
103+
* @brief Intercepts the bowling ball model after construction to apply patches
104+
*
105+
* @param pModel Bowling ball model
106+
*/
107+
void InterceptBwlBallConstruct(RPGrpModelG3D* pModel) {
108+
ASSERT_PTR(pModel);
109+
110+
static kiwi::Color color;
111+
static int numCalls = 0;
112+
113+
/**
114+
* Every two calls to this function will be one for the regular model and
115+
* one for the mirror model.
116+
*
117+
* We re-randomize the color after each set of two.
118+
*/
119+
if (numCalls % 2 == 0) {
120+
color = kiwi::Color::FromHsv(kiwi::RNG.NextF32(1.0f), 1.0f, 1.0f);
121+
}
122+
123+
PatchBwlBallColor(pModel, numCalls % 2 != 0, color);
124+
numCalls++;
125+
}
126+
127+
/**
128+
* @brief InterceptBwlBallConstruct common trampoline code
129+
*/
130+
asm void BwlBallCmnTrampoline(...) {
131+
// clang-format off
132+
TRAMPOLINE_BEGIN
133+
134+
// Enable ScnMdl BUFFER_RESTEV buffer option
135+
ori r7, r7, (1 << 11)
136+
137+
// RPGrpModelG3D::Construct
138+
lis r12, 0x8024E630@h
139+
ori r12, r12, 0x8024E630@l
140+
mtctr r12
141+
bctrl
142+
mr r31, r3
143+
144+
// Patch the resulting model
145+
bl InterceptBwlBallConstruct
146+
147+
mr r0, r31
148+
TRAMPOLINE_END
149+
mr r3, r0
150+
blr
151+
// clang-format on
152+
}
153+
154+
/**
155+
* @brief Hook all relevant RPGrpModelG3D::Construct calls
156+
*/
157+
KM_CALL(0x804c89e0, BwlBallCmnTrampoline);
158+
KM_CALL(0x804c89fc, BwlBallCmnTrampoline);
159+
KM_CALL(0x804c8a30, BwlBallCmnTrampoline);
160+
KM_CALL(0x804c8a4c, BwlBallCmnTrampoline);
161+
162+
KM_CALL(0x804c9cb0, BwlBallCmnTrampoline);
163+
KM_CALL(0x804c9ccc, BwlBallCmnTrampoline);
164+
165+
KM_CALL(0x804c9f60, BwlBallCmnTrampoline);
166+
KM_CALL(0x804c9f7c, BwlBallCmnTrampoline);
167+
KM_CALL(0x804c9fb0, BwlBallCmnTrampoline);
168+
KM_CALL(0x804c9fcc, BwlBallCmnTrampoline);
169+
170+
} // namespace Cosmetic
171+
} // namespace Bwl
172+
} // namespace AP

0 commit comments

Comments
 (0)