From 7aa3766d6728823c16e9b3771fd3d29bca1cc712 Mon Sep 17 00:00:00 2001 From: Parker Burnett Date: Sun, 16 Jan 2022 08:37:21 -0600 Subject: [PATCH] En_hgOK (#394) * en_hgo OK * Formatting changed somehow?...hopefully this fixes * who would win, Cammoguy or one letter? * format * addressing review comments * fixing PR comments * fixing and merging master * forgot to format * fixes warnings? * minor documentation...don't have tools to do more * Fixing things, hopefully OK * formatting... * clean-up undefined syms --- spec | 3 +- src/overlays/actors/ovl_En_Hgo/z_en_hgo.c | 358 ++++++++++++++++++++-- src/overlays/actors/ovl_En_Hgo/z_en_hgo.h | 44 ++- tools/disasm/functions.txt | 8 +- undefined_syms.txt | 7 - 5 files changed, 374 insertions(+), 46 deletions(-) diff --git a/spec b/spec index f86a1d585a..dcf40880ec 100644 --- a/spec +++ b/spec @@ -4748,8 +4748,7 @@ beginseg name "ovl_En_Hgo" compress include "build/src/overlays/actors/ovl_En_Hgo/z_en_hgo.o" - include "build/data/ovl_En_Hgo/ovl_En_Hgo.data.o" - include "build/data/ovl_En_Hgo/ovl_En_Hgo.reloc.o" + include "build/src/overlays/actors/ovl_En_Hgo/ovl_En_Hgo_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_En_Hgo/z_en_hgo.c b/src/overlays/actors/ovl_En_Hgo/z_en_hgo.c index 1793384019..2e2b6a84b3 100644 --- a/src/overlays/actors/ovl_En_Hgo/z_en_hgo.c +++ b/src/overlays/actors/ovl_En_Hgo/z_en_hgo.c @@ -5,6 +5,7 @@ */ #include "z_en_hgo.h" +#include "objects/object_harfgibud/object_harfgibud.h" #define FLAGS 0x02000019 @@ -15,7 +16,18 @@ void EnHgo_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnHgo_Update(Actor* thisx, GlobalContext* globalCtx); void EnHgo_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80BD03EC(EnHgo* this); +void func_80BD0410(EnHgo* this, GlobalContext* globalCtx); +void func_80BD0434(EnHgo* this, GlobalContext* globalCtx); +void func_80BD049C(EnHgo* this); +void func_80BD04E0(EnHgo* this, GlobalContext* globalCtx); +void EnHgo_SetupDialogueHandler(EnHgo* this); +void EnHgo_DefaultDialogueHandler(EnHgo* this, GlobalContext* globalCtx); +void func_80BD06FC(EnHgo* this, GlobalContext* globalCtx); +s32 func_80BD0898(EnHgo* this, GlobalContext* globalCtx); +s32 EnHgo_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx); +void EnHgo_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* pos, Actor* thisx); + const ActorInit En_Hgo_InitVars = { ACTOR_EN_HGO, ACTORCAT_NPC, @@ -28,54 +40,342 @@ const ActorInit En_Hgo_InitVars = { (ActorFunc)EnHgo_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80BD0F48 = { - { COLTYPE_NONE, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, +static ActorAnimationEntry sAnimations[] = { + { &object_harfgibud_Anim_00B644, 1.0f, 0.0f, 0.0f, 0, -4.0f }, + { &object_harfgibud_Anim_013684, 1.0f, 0.0f, 0.0f, 0, 0.0f }, + { &object_harfgibud_Anim_0152EC, 1.0f, 0.0f, 0.0f, 2, 0.0f }, + { &object_harfgibud_Anim_015C70, 1.0f, 0.0f, 0.0f, 0, 0.0f }, + { &object_harfgibud_Anim_0165F0, 1.0f, 0.0f, 0.0f, 0, 0.0f }, + { &object_harfgibud_Anim_014220, 1.0f, 0.0f, 0.0f, 2, 0.0f }, + { &object_harfgibud_Anim_014A9C, 1.0f, 0.0f, 0.0f, 0, 0.0f }, +}; + +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_NONE, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 18, 46, 0, { 0, 0, 0 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_80BD0F74 = { 0, 0, 0, 0, MASS_IMMOVABLE }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 0, 0, 0, 0, MASS_IMMOVABLE }; -#endif +static TexturePtr sEyeTextures[] = { + object_harfgibud_Tex_011138, + object_harfgibud_Tex_011938, + object_harfgibud_Tex_012138, +}; -extern ColliderCylinderInit D_80BD0F48; -extern CollisionCheckInfoInit2 D_80BD0F74; +void EnHgo_Init(Actor* thisx, GlobalContext* globalCtx) { + EnHgo* this = THIS; + s32 pad; -extern UNK_TYPE D_0600B644; -extern UNK_TYPE D_0600F248; + ActorShape_Init(&thisx->shape, 0.0f, ActorShadow_DrawCircle, 36.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_harfgibud_Skel_012A58, &object_harfgibud_Anim_00B644, + this->jointTable, this->morphTable, HGO_LIMB_MAX); + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + CollisionCheck_SetInfo2(&thisx->colChkInfo, NULL, &sColChkInfoInit); + thisx->targetMode = 6; + this->unk_30C = 0; + this->unk_30E = 0; + this->unk_314 = 0; + this->unk_310 = 0; + this->unk_312 = 0; + if ((gSaveContext.weekEventReg[75] & 0x20) || (gSaveContext.weekEventReg[52] & 0x20)) { + func_80BD049C(this); + } else { + thisx->draw = NULL; + func_80BD03EC(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/EnHgo_Init.s") +void EnHgo_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnHgo* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/EnHgo_Destroy.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD03EC.s") +void func_80BD03EC(EnHgo* this) { + this->actor.flags &= ~1; + this->actionFunc = func_80BD0410; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD0410.s") +void func_80BD0410(EnHgo* this, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD0420.s") +void func_80BD0420(EnHgo* this) { + this->actionFunc = func_80BD0434; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD0434.s") +void func_80BD0434(EnHgo* this, GlobalContext* globalCtx) { + this->collider.dim.pos.x = this->actor.focus.pos.x; + this->collider.dim.pos.y = this->actor.world.pos.y; + this->collider.dim.pos.z = this->actor.focus.pos.z; + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD049C.s") +void func_80BD049C(EnHgo* this) { + Actor_ChangeAnimation(&this->skelAnime, sAnimations, 0); + this->actionFunc = func_80BD04E0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD04E0.s") +void func_80BD04E0(EnHgo* this, GlobalContext* globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + if (Player_GetMask(globalCtx) == PLAYER_MASK_GIBDO) { + if (!(this->unk_310 & 4)) { + this->unk_310 |= 4; + func_801518B0(globalCtx, 0x15A5, &this->actor); + this->unk_314 = 0x15A5; // That mask is a gibdo -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD064C.s") + } else { + func_801518B0(globalCtx, 0x15A7, &this->actor); + this->unk_314 = 0x15A7; // can I research that mask + } + } else if (gSaveContext.playerForm == PLAYER_FORM_HUMAN) { + if (!(this->unk_310 & 1)) { + this->unk_310 |= 1; + func_801518B0(globalCtx, 0x158F, &this->actor); + this->unk_314 = 0x158F; // Isn't this a fairy + } else { + func_801518B0(globalCtx, 0x1593, &this->actor); + this->unk_314 = 0x1593; // Never seen a fairy this lively + } + } else { + if (!(this->unk_310 & 2)) { + this->unk_310 |= 2; + func_801518B0(globalCtx, 0x1595, &this->actor); + this->unk_314 = 0x1595; // ghost radar is reacting + } else { + func_801518B0(globalCtx, 0x1598, &this->actor); + this->unk_314 = 0x1598; // you seem to be similar to a ghost + } + } + EnHgo_SetupDialogueHandler(this); + } else { + func_800B8614(&this->actor, globalCtx, 100.0f); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD0660.s") +void EnHgo_SetupDialogueHandler(EnHgo* this) { + this->actionFunc = EnHgo_DefaultDialogueHandler; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD06FC.s") +void EnHgo_DefaultDialogueHandler(EnHgo* this, GlobalContext* globalCtx) { + switch (Message_GetState(&globalCtx->msgCtx)) { + case 0: + case 1: + case 2: + case 3: + case 4: + break; + case 5: + func_80BD06FC(this, globalCtx); + break; + case 6: + if (func_80147624(globalCtx)) { + func_80BD049C(this); + } + } + Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 0xA, 0x71C, 0xB6); + this->actor.shape.rot.y = this->actor.world.rot.y; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD0898.s") +void func_80BD06FC(EnHgo* this, GlobalContext* globalCtx) { + if (func_80147624(globalCtx)) { + switch (this->unk_314) { + case 0x158F: + func_801518B0(globalCtx, 0x1590, &this->actor); + this->unk_314 = 0x1590; + break; + case 0x1590: + if (gSaveContext.weekEventReg[14] & 4) { + func_801518B0(globalCtx, 0x1591, &this->actor); + this->unk_314 = 0x1591; + break; + } + func_801518B0(globalCtx, 0x1592, &this->actor); + this->unk_314 = 0x1592; + break; + case 0x1591: + func_801518B0(globalCtx, 0x1592, &this->actor); + this->unk_314 = 0x1592; + break; + case 0x1593: + func_801518B0(globalCtx, 0x1594, &this->actor); + this->unk_314 = 0x1594; + break; + case 0x1595: + func_801518B0(globalCtx, 0x1596, &this->actor); + this->unk_314 = 0x1596; + break; + case 0x1596: + func_801518B0(globalCtx, 0x1597, &this->actor); + this->unk_314 = 0x1597; + break; + case 0x1598: + func_801518B0(globalCtx, 0x1599, &this->actor); + this->unk_314 = 0x1599; + break; + case 0x15A5: + func_801518B0(globalCtx, 0x15A6, &this->actor); + this->unk_314 = 0x15A6; + break; + case 0x15A6: + func_801518B0(globalCtx, 0x15A7, &this->actor); + this->unk_314 = 0x15A7; + break; + case 0x15A7: + func_801477B4(globalCtx); + func_80BD049C(this); + break; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD0B8C.s") +s32 func_80BD0898(EnHgo* this, GlobalContext* globalCtx) { + u32 actionIndex; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/EnHgo_Update.s") + if (func_800EE29C(globalCtx, 0x1E6)) { + actionIndex = func_800EE200(globalCtx, 0x1E6); + if (this->unk_316 != globalCtx->csCtx.npcActions[actionIndex]->unk0) { + this->unk_316 = globalCtx->csCtx.npcActions[actionIndex]->unk0; + switch (globalCtx->csCtx.npcActions[actionIndex]->unk0) { + case 1: + this->unk_218 = 0; + Actor_ChangeAnimation(&this->skelAnime, sAnimations, 0); + break; + case 2: + this->actor.draw = EnHgo_Draw; + this->unk_218 = 1; + Actor_ChangeAnimation(&this->skelAnime, sAnimations, 1); + break; + case 3: + this->unk_218 = 2; + Actor_ChangeAnimation(&this->skelAnime, sAnimations, 2); + break; + case 4: + this->unk_218 = 3; + Actor_ChangeAnimation(&this->skelAnime, sAnimations, 3); + break; + case 5: + this->unk_218 = 4; + Actor_ChangeAnimation(&this->skelAnime, sAnimations, 4); + break; + case 6: + this->unk_218 = 5; + Actor_ChangeAnimation(&this->skelAnime, sAnimations, 5); + break; + } + } else if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + switch (this->unk_218) { + case 1: + if ((Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) && (this->unk_312 == 0)) { + this->unk_312 = 1; + if ((gSaveContext.sceneSetupIndex == 0) && + ((globalCtx->csCtx.unk_12 == 2) || (globalCtx->csCtx.unk_12 == 4))) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_VO_GBVO02); + } + } + break; + case 2: + this->unk_218 = 3; + Actor_ChangeAnimation(&this->skelAnime, sAnimations, 3); + break; + case 5: + this->unk_218 = 6; + Actor_ChangeAnimation(&this->skelAnime, sAnimations, 6); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD0CF0.s") + func_800EDF24(&this->actor, globalCtx, actionIndex); + return true; + } + if ((globalCtx->csCtx.state == 0) && (((gSaveContext.weekEventReg[75]) & 0x20)) && + (this->actionFunc == func_80BD0410)) { + this->actor.shape.rot.y = this->actor.world.rot.y; + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_ELF_MSG2, this->actor.focus.pos.x, this->actor.focus.pos.y, + this->actor.focus.pos.z, 7, 0, 0, 0x7F5A); + func_80BD0420(this); + } + this->unk_316 = 0x63; + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD0D38.s") +void func_80BD0B8C(EnHgo* this, GlobalContext* globalCtx) { + func_800E9250(globalCtx, &this->actor, &this->unk_300, &this->unk_306, this->actor.focus.pos); + if (this->unk_30E > 2) { + this->unk_30E--; + } else if (this->unk_30E == 2) { + this->unk_30C = 1; + this->unk_30E = 1; + } else if (this->unk_30E == 1) { + this->unk_30C = 2; + this->unk_30E = 0; + } else { + this->unk_30C = 0; + this->unk_30E = 60; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/EnHgo_Draw.s") +void EnHgo_Update(Actor* thisx, GlobalContext* globalCtx) { + EnHgo* this = THIS; + s32 pad; + + this->actionFunc(this, globalCtx); + SkelAnime_Update(&this->skelAnime); + if (func_80BD0898(this, globalCtx)) { + func_800E8F08(&this->unk_300, &this->unk_306); + } else if (this->actionFunc != func_80BD0410) { + if (this->actionFunc != func_80BD0434) { + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + func_80BD0B8C(this, globalCtx); + } + } +} + +s32 EnHgo_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnHgo* this = THIS; + + if (limbIndex == HGO_LIMB_PELVIS) { + rot->x += this->unk_300.y; + rot->z += this->unk_300.x; + } + return false; +} + +void EnHgo_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* pos, Actor* thisx) { + EnHgo* this = THIS; + + if (limbIndex == HGO_LIMB_PELVIS) { + Matrix_CopyCurrentState(&this->unk_1D8); + Matrix_GetStateTranslation(&this->actor.focus.pos); + } +} + +void EnHgo_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnHgo* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + func_8012C28C(globalCtx->state.gfxCtx); + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sEyeTextures[this->unk_30C])); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnHgo_OverrideLimbDraw, &EnHgo_PostLimbDraw, &this->actor); + Matrix_SetCurrentState(&this->unk_1D8); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, object_harfgibud_DL_00F248); + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Hgo/z_en_hgo.h b/src/overlays/actors/ovl_En_Hgo/z_en_hgo.h index 3d7ff6e558..f39aab0fdf 100644 --- a/src/overlays/actors/ovl_En_Hgo/z_en_hgo.h +++ b/src/overlays/actors/ovl_En_Hgo/z_en_hgo.h @@ -7,11 +7,47 @@ struct EnHgo; typedef void (*EnHgoActionFunc)(struct EnHgo*, GlobalContext*); +// Shares the same setup as en_hg +typedef enum { + /* 00 */ HGO_LIMB_NONE, + /* 01 */ HGO_LIMB_ABDOMEN, + /* 02 */ HGO_LIMB_CHEST, + /* 03 */ HGO_LIMB_SHOULDER_LEFT, + /* 04 */ HGO_LIMB_ARM_LEFT, + /* 05 */ HGO_LIMB_HAND_LEFT, + /* 06 */ HGO_LIMB_SHOULDER_RIGHT, + /* 07 */ HGO_LIMB_ARM_RIGHT, + /* 08 */ HGO_LIMB_HAND_RIGHT, + /* 09 */ HGO_LIMB_EYEBROW, + /* 10 */ HGO_LIMB_HEAD, + /* 11 */ HGO_LIMB_PELVIS, + /* 12 */ HGO_LIMB_THIGH_LEFT, + /* 13 */ HGO_LIMB_LEG_LEFT, + /* 14 */ HGO_LIMB_FOOT_LEFT, + /* 15 */ HGO_LIMB_THIGH_RIGHT, + /* 16 */ HGO_LIMB_LEG_RIGHT, + /* 17 */ HGO_LIMB_FOOT_RIGHT, + /* 18 */ HGO_LIMB_UNK, + /* 19 */ HGO_LIMB_MAX, +} ObjectHgoLimbs; + typedef struct EnHgo { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x90]; - /* 0x01D4 */ EnHgoActionFunc actionFunc; - /* 0x01D8 */ char unk_1D8[0x140]; + /* 0x000 */ Actor actor; + /* 0x144 */ ColliderCylinder collider; + /* 0x190 */ SkelAnime skelAnime; + /* 0x1D4 */ EnHgoActionFunc actionFunc; + /* 0x1D8 */ MtxF unk_1D8; + /* 0x218 */ s32 unk_218; + /* 0x21C */ Vec3s jointTable[HGO_LIMB_MAX]; + /* 0x28E */ Vec3s morphTable[HGO_LIMB_MAX]; + /* 0x300 */ Vec3s unk_300; + /* 0x306 */ Vec3s unk_306; + /* 0x30C */ s16 unk_30C; + /* 0x30E */ s16 unk_30E; + /* 0x310 */ s16 unk_310; + /* 0x312 */ s16 unk_312; + /* 0x314 */ u16 unk_314; + /* 0x316 */ u16 unk_316; } EnHgo; // size = 0x318 extern const ActorInit En_Hgo_InitVars; diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 69ca079a9b..fe6a3dfdbf 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -15700,14 +15700,14 @@ 0x80BD0434:("func_80BD0434",), 0x80BD049C:("func_80BD049C",), 0x80BD04E0:("func_80BD04E0",), - 0x80BD064C:("func_80BD064C",), - 0x80BD0660:("func_80BD0660",), + 0x80BD064C:("EnHgo_SetupDialogueHandler",), + 0x80BD0660:("EnHgo_DefaultDialogueHandler",), 0x80BD06FC:("func_80BD06FC",), 0x80BD0898:("func_80BD0898",), 0x80BD0B8C:("func_80BD0B8C",), 0x80BD0C30:("EnHgo_Update",), - 0x80BD0CF0:("func_80BD0CF0",), - 0x80BD0D38:("func_80BD0D38",), + 0x80BD0CF0:("EnHgo_OverrideLimbDraw",), + 0x80BD0D38:("EnHgo_PostLimbDraw",), 0x80BD0D7C:("EnHgo_Draw",), 0x80BD11E0:("EnZov_Init",), 0x80BD13B0:("EnZov_Destroy",), diff --git a/undefined_syms.txt b/undefined_syms.txt index 9cca916c00..1168dbcab6 100644 --- a/undefined_syms.txt +++ b/undefined_syms.txt @@ -2412,13 +2412,6 @@ D_06009D44 = 0x06009D44; D_0600A164 = 0x0600A164; D_0600AE1C = 0x0600AE1C; - -// ovl_En_Hgo - -D_0600B644 = 0x0600B644; -D_0600F248 = 0x0600F248; -D_06012A58 = 0x06012A58; - // ovl_En_Hidden_Nuts D_060023B8 = 0x060023B8;