3#include <actor/Actor.h>
4#include <telkin/Print.h>
12 return static_cast<
SpriteUtil*>(target)->mSwitchFlag1 >> 0x04 & 0xF;
17 return static_cast<
SpriteUtil*>(target)->mSwitchFlag1 >> 0x00 & 0xF;
22 return static_cast<
SpriteUtil*>(target)->mSwitchFlag0 >> 0x04 & 0xF;
27 return static_cast<
SpriteUtil*>(target)->mSwitchFlag0 >> 0x00 & 0xF;
32 return static_cast<
SpriteUtil*>(target)->mParam0 >> 0x1C & 0xF;
37 return static_cast<
SpriteUtil*>(target)->mParam0 >> 0x18 & 0xF;
42 return static_cast<
SpriteUtil*>(target)->mParam0 >> 0x14 & 0xF;
47 return static_cast<
SpriteUtil*>(target)->mParam0 >> 0x10 & 0xF;
52 return static_cast<
SpriteUtil*>(target)->mParam0 >> 0x0C & 0xF;
57 return static_cast<
SpriteUtil*>(target)->mParam0 >> 0x08 & 0xF;
62 return static_cast<
SpriteUtil*>(target)->mParam0 >> 0x04 & 0xF;
67 return static_cast<
SpriteUtil*>(target)->mParam0 >> 0x00 & 0xF;
72 return static_cast<
SpriteUtil*>(target)->mParam1 >> 0x1C & 0xF;
77 return static_cast<
SpriteUtil*>(target)->mParam1 >> 0x18 & 0xF;
82 return static_cast<
SpriteUtil*>(target)->mParam1 >> 0x14 & 0xF;
87 return static_cast<
SpriteUtil*>(target)->mParam1 >> 0x10 & 0xF;
92 return static_cast<
SpriteUtil*>(target)->mParam1 >> 0x0C & 0xF;
97 return static_cast<
SpriteUtil*>(target)->mParam1 >> 0x08 & 0xF;
102 return static_cast<
SpriteUtil*>(target)->mParam1 >> 0x04 & 0xF;
107 return static_cast<
SpriteUtil*>(target)->mParam1 >> 0x00 & 0xF;
112 return static_cast<
SpriteUtil*>(target)->mParamEx.course.movement_id >> 0x04 & 0xF;
117 return static_cast<
SpriteUtil*>(target)->mParamEx.course.movement_id >> 0x00 & 0xF;
122 return static_cast<
SpriteUtil*>(target)->mParamEx.course.link_id >> 0x04 & 0xF;
127 return static_cast<
SpriteUtil*>(target)->mParamEx.course.link_id >> 0x00 & 0xF;
133
134
135
136
137
138
139
140
143 const u8 nybbleCount = end - (from - 1);
144 if (nybbleCount == 0 || nybbleCount > 8 || from > 24 || end > 24) {
145 tk::fatal(
"red::SpriteUtil::getNybbleRange called with an invalid nybble range. (%i - %i)", from, end);
147 return getBitRange(target, from * 4 - 4, end * 4);
151
152
153
154
155
156
157
158
159
160
163 const u8 bitsCount = end - from;
164 if (bitsCount == 0 || bitsCount > 32 || from > 96 || end > 96) {
165 tk::fatal(
"red::SpriteUtil::getBitRange called with an invalid bit range. (%i - %i)", from, end);
172 u32 flags = (
static_cast<u32>(actor->mSwitchFlag1) << 8) | actor->mSwitchFlag0;
173 return getBitRangeInt32(flags << 16, from, end);
176 if (from >= 16 && end <= 48) {
177 return getBitRangeInt32(actor->mParam0, from - 16, end - 16);
180 if (from >= 48 && end <= 80) {
181 return getBitRangeInt32(actor->mParam1, from - 48, end - 48);
185 u32 paramEx = (
static_cast<u32>(actor->mParamEx.course.movement_id) << 8) | actor->mParamEx.course.link_id;
186 return getBitRangeInt32(paramEx << 16, from - 80, end - 80);
197 upperField = (
static_cast<u32>(actor->mSwitchFlag1) << 8) | actor->mSwitchFlag0;
199 lowerField = actor->mParam0;
201 else if (from < 48) {
203 upperField = actor->mParam0;
204 lowerField = actor->mParam1;
208 upperField = actor->mParam1;
209 lowerField = (
static_cast<u32>(actor->mParamEx.course.movement_id) << 8) | actor->mParamEx.course.link_id;
214 const u8 upperBitsCount = boundaryBit - from;
215 const u8 lowerBitsCount = bitsCount - upperBitsCount;
217 const u32 upperValue = getBitRangeInt32(upperField, 32 - upperBitsCount, 32);
218 const u32 lowerValue = getBitRangeInt32(lowerField, 0, lowerBitsCount);
220 return (upperValue << lowerBitsCount) | lowerValue;
224
225
226
227
228
229
230
231
232
233
234
235
236
237 template <u8 TFrom, u8 TEnd, s32 TOutBytes>
238 static void getBitRange(
const Actor* target, u8 (&out)[TOutBytes]) {
239 static_assert(TFrom <= 96 && TEnd <= 96,
"getBitRange: Bit range out of bounds (max 96).");
240 static_assert(TEnd > TFrom,
"getBitRange: End index must be strictly greater than From index.");
242 constexpr u8 bitsCount = TEnd - TFrom;
243 constexpr u8 outBytesCount = (bitsCount + 7) / 8;
245 static_assert(TOutBytes >= outBytesCount,
"getBitRange: Output buffer is too small for the requested bit range.");
248 if constexpr (bitsCount <= 32) {
249 u32 val = getBitRange(target, TFrom, TEnd);
250 for (u8 i = 0; i < outBytesCount; i++) {
251 out[i] =
static_cast<u8>((val >> ((outBytesCount - 1 - i) * 8)) & 0xFF);
258 src[0] = actor->mSwitchFlag1;
259 src[1] = actor->mSwitchFlag0;
260 src[2] =
static_cast<u8>((actor->mParam0 >> 24) & 0xFF);
261 src[3] =
static_cast<u8>((actor->mParam0 >> 16) & 0xFF);
262 src[4] =
static_cast<u8>((actor->mParam0 >> 8) & 0xFF);
263 src[5] =
static_cast<u8>( actor->mParam0 & 0xFF);
264 src[6] =
static_cast<u8>((actor->mParam1 >> 24) & 0xFF);
265 src[7] =
static_cast<u8>((actor->mParam1 >> 16) & 0xFF);
266 src[8] =
static_cast<u8>((actor->mParam1 >> 8) & 0xFF);
267 src[9] =
static_cast<u8>( actor->mParam1 & 0xFF);
268 src[10] = actor->mParamEx.course.movement_id;
269 src[11] = actor->mParamEx.course.link_id;
271 constexpr u8 paddingBits = (8 - (bitsCount % 8)) % 8;
273 for (u8 i = 0; i < outBytesCount; i++) {
277 for (u8 i = 0; i < bitsCount; i++) {
278 const u8 srcBitIdx = TFrom + i;
279 const u8 destBitIdx = paddingBits + i;
281 const u8 srcBit = (src[srcBitIdx / 8] >> (7 - (srcBitIdx % 8))) & 1;
282 out[destBitIdx / 8] |= (srcBit << (7 - (destBitIdx % 8)));
290 static u32 getBitRangeInt32(u32 num, u8 from, u8 end) {
291 const u8 bitsCount = end - from;
292 if (bitsCount >= 32) {
295 const u32 shifted = num >> (32 - end);
296 const u32 mask = (1U << bitsCount) - 1;
297 return shifted & mask;
Definition SpriteUtil.h:8
static u8 getNybble23(Actor *target)
Definition SpriteUtil.h:121
static u8 getNybble20(Actor *target)
Definition SpriteUtil.h:106
static u8 getNybble5(Actor *target)
Definition SpriteUtil.h:31
static u8 getNybble3(Actor *target)
Definition SpriteUtil.h:21
static u8 getNybble8(Actor *target)
Definition SpriteUtil.h:46
static u8 getNybble16(Actor *target)
Definition SpriteUtil.h:86
static u8 getNybble15(Actor *target)
Definition SpriteUtil.h:81
static u8 getNybble6(Actor *target)
Definition SpriteUtil.h:36
static u32 getNybbleRange(Actor *target, u8 from, u8 end)
Extract the combined value of a range of up to 8 sequential nybbles from the given actor's full 24 ny...
Definition SpriteUtil.h:142
static u8 getNybble18(Actor *target)
Definition SpriteUtil.h:96
static u8 getNybble21(Actor *target)
Definition SpriteUtil.h:111
static u8 getNybble2(Actor *target)
Definition SpriteUtil.h:16
static u32 getBitRange(const Actor *target, u8 from, u8 end)
Extract the value of an arbitrary 32-bit range of bits from the given actor's full 96 bits of sprited...
Definition SpriteUtil.h:162
static u8 getNybble4(Actor *target)
Definition SpriteUtil.h:26
static u8 getNybble1(Actor *target)
Definition SpriteUtil.h:11
static u8 getNybble11(Actor *target)
Definition SpriteUtil.h:61
static u8 getNybble10(Actor *target)
Definition SpriteUtil.h:56
static u8 getNybble22(Actor *target)
Definition SpriteUtil.h:116
static u8 getNybble17(Actor *target)
Definition SpriteUtil.h:91
static u8 getNybble9(Actor *target)
Definition SpriteUtil.h:51
static u8 getNybble7(Actor *target)
Definition SpriteUtil.h:41
static u8 getNybble19(Actor *target)
Definition SpriteUtil.h:101
static u8 getNybble13(Actor *target)
Definition SpriteUtil.h:71
static void getBitRange(const Actor *target, u8(&out)[TOutBytes])
Extract a compile-time defined range of bits (up to 96) from the given actor's spritedata....
Definition SpriteUtil.h:238
static u8 getNybble24(Actor *target)
Definition SpriteUtil.h:126
static u8 getNybble14(Actor *target)
Definition SpriteUtil.h:76
static u8 getNybble12(Actor *target)
Definition SpriteUtil.h:66
Definition ActorDonutBlock.h:5