diff --git a/asm/src/code_08000F10.s b/asm/src/code_08000F10.s index e7ce35aa..7ecc84d5 100644 --- a/asm/src/code_08000F10.s +++ b/asm/src/code_08000F10.s @@ -10,41 +10,43 @@ CheckBits: @ 0x08000F10 ldr r3, _08000F50 @ =ram_CheckBits bx r3 - thumb_func_start sub_08000F14 -sub_08000F14: @ 0x08000F14 + // sum 3 drop probability vectors + thumb_func_start SumDropProbabilities +SumDropProbabilities: @ 0x08000F14 push {r4, r5, r6} - movs r4, #0x1e + movs r4, #30 // vector addition for 16 shorts in reverse _08000F18: - ldrsh r5, [r1, r4] - ldrsh r6, [r2, r4] - adds r5, r5, r6 - ldrsh r6, [r3, r4] - adds r5, r5, r6 - strh r5, [r0, r4] + ldrsh r5, [r1, r4] // row 1 + ldrsh r6, [r2, r4] // + row 2 + adds r5, r6 + ldrsh r6, [r3, r4] // + row 3 + adds r5, r6 + strh r5, [r0, r4] // store in output subs r4, #2 bpl _08000F18 pop {r4, r5, r6} bx lr - thumb_func_start sub_08000F2C -sub_08000F2C: @ 0x08000F2C + // sum 3 drop probabilities, clamp to 0, return scalar sum + thumb_func_start SumDropProbabilities2 +SumDropProbabilities2: @ 0x08000F2C push {r4, r5, r6, r7} - movs r4, #0x1e - movs r7, #0 + movs r4, #30 + movs r7, #0 // sum _08000F32: - ldrsh r5, [r1, r4] - ldrsh r6, [r2, r4] - adds r5, r5, r6 - ldrsh r6, [r3, r4] - adds r5, r5, r6 - bpl _08000F40 + ldrsh r5, [r1, r4] // row 1 + ldrsh r6, [r2, r4] // + row 2 + adds r5, r6 + ldrsh r6, [r3, r4] // + row 3 + adds r5, r6 + bpl positive_drop_chance // clamp to 0 movs r5, #0 -_08000F40: - strh r5, [r0, r4] - adds r7, r7, r5 +positive_drop_chance: + strh r5, [r0, r4] // store in output + adds r7, r5 subs r4, #2 bpl _08000F32 - adds r0, r7, #0 + adds r0, r7, #0 // return sum pop {r4, r5, r6, r7} bx lr .align 2, 0 diff --git a/include/entity.h b/include/entity.h index 5b5c328d..067e9ff4 100644 --- a/include/entity.h +++ b/include/entity.h @@ -6,7 +6,9 @@ #include "color.h" #include "sprite.h" -#define MAX_ENTITIES 71 +#define MAX_ENTITIES 72 +#define MAX_MANAGERS 32 +#define MAX_AUX_PLAYER_ENTITIES 7 /** Kinds of Entity's supported by the game. */ typedef enum { @@ -38,6 +40,8 @@ typedef enum { typedef enum { ENT_DID_INIT = 0x1, /**< Graphics and other data loaded. */ ENT_SCRIPTED = 0x2, /**< Execute in a scripted environment. */ + ENT_UNUSED1 = 0x4, /**< Unused delete flag. */ + ENT_UNUSED2 = 0x8, /**< Unused delete flag. */ ENT_DELETED = 0x10, /**< Queue deletion next frame. */ ENT_PERSIST = 0x20, /**< Persist between rooms. */ ENT_COLLIDE = 0x80, /**< Collide with other Entity's. */ @@ -238,6 +242,15 @@ typedef struct LinkedList { Entity* first; } LinkedList; +/** + * LinkedList's which point to allocate Entities. + * These work together with Entity.prev and Entity.next fields + * to allow the iteration of all Entity's. + */ +extern LinkedList gEntityLists[9]; +extern Entity gAuxPlayerEntities[MAX_AUX_PLAYER_ENTITIES]; +extern Entity gEntities[MAX_ENTITIES]; + typedef void(EntityAction)(Entity*); typedef void (*EntityActionPtr)(Entity*); typedef void (*const* EntityActionArray)(Entity*); @@ -283,7 +296,7 @@ Entity* CreateEnemy(u32 id, u32 type); Entity* CreateNPC(u32 id, u32 type, u32 type2); Entity* CreateObject(u32 id, u32 type, u32 type2); Entity* CreateObjectWithParent(Entity* parent, u32 id, u32 type, u32 type2); -Entity* CreateItemGetEntity(void); +Entity* CreateAuxPlayerEntity(void); Entity* CreateFx(Entity* parent, u32 type, u32 type2); /// @} @@ -484,14 +497,6 @@ void ClearEventPriority(void); void sub_0805E958(void); -/** - * LinkedList's which point to allocate Entities. - * These work together with Entity.prev and Entity.next fields - * to allow the iteration of all Entity's. - */ -extern LinkedList gEntityLists[9]; -extern Entity gItemGetEntities[7]; - typedef struct { u8 unk_0; u8 unk_1; diff --git a/include/structures.h b/include/structures.h index 6125cba9..f4dc51cd 100644 --- a/include/structures.h +++ b/include/structures.h @@ -192,7 +192,7 @@ static_assert(sizeof(gActiveItems) == 0x70); typedef struct { u8 event_priority; // system requested priority - u8 ent_priority; // entity requested priority + u8 ent_priority; // entity requested priority u8 queued_priority; u8 queued_priority_reset; Entity* requester; diff --git a/linker.ld b/linker.ld index dbfc5c3c..18f9d27d 100644 --- a/linker.ld +++ b/linker.ld @@ -132,8 +132,8 @@ SECTIONS { . = 0x000010A0; gRoomTransition = .; . = 0x00001150; gRand = .; . = 0x00001160; gPlayerEntity = .; - . = 0x000011E8; gItemGetEntities = .; - . = 0x000015A0; gUnk_030015A0 = .; + . = 0x000011E8; gAuxPlayerEntities = .; + . = 0x000015A0; gEntities = .; . = 0x00003BE0; gCarriedEntity = .; . = 0x00003C70; gUnk_03003C70 = .; . = 0x00003D70; gEntityLists = .; diff --git a/src/enemy/acroBandits.c b/src/enemy/acroBandits.c index aeeed7f6..58457d1d 100644 --- a/src/enemy/acroBandits.c +++ b/src/enemy/acroBandits.c @@ -240,7 +240,7 @@ void AcroBandit_Type0Action5(Entity* this) { GetNextFrame(this); if (this->frame & ANIM_DONE) { - if (gEntCount < MAX_ENTITIES - 4) { + if (gEntCount < MAX_ENTITIES - 5) { u32 tmp = Random(); tmp &= 3; diff --git a/src/enemy/fireballGuy.c b/src/enemy/fireballGuy.c index 3eb404a1..0aeaf781 100644 --- a/src/enemy/fireballGuy.c +++ b/src/enemy/fireballGuy.c @@ -81,7 +81,7 @@ void FireballGuy_Action2(Entity* this) { /* Can we create enough new entities? */ count = typeEntityCount[this->type]; - if (MAX_ENTITIES + 1 - count <= gEntCount) + if (MAX_ENTITIES - count <= gEntCount) return; /* Create 2-5 new MiniFireballGuy */ diff --git a/src/enemy/slime.c b/src/enemy/slime.c index 494d0459..47bf27b5 100644 --- a/src/enemy/slime.c +++ b/src/enemy/slime.c @@ -105,7 +105,7 @@ void sub_080450A8(Entity* this) { /* Can we create enough new entities? */ count = typeEntityCount[this->type]; - if (MAX_ENTITIES + 1 - count <= gEntCount) + if (MAX_ENTITIES - count <= gEntCount) return; /* Create 2-4 new MiniSlime */ diff --git a/src/entity.c b/src/entity.c index b93fa3a3..b13d5261 100644 --- a/src/entity.c +++ b/src/entity.c @@ -6,6 +6,12 @@ #include "npc.h" #include "manager/diggingCaveEntranceManager.h" +typedef struct Temp { + void* prev; + void* next; + u8 _0[0x38]; +} Temp; + extern u8 gUpdateVisibleTiles; extern Manager gUnk_02033290; void UpdatePlayerInput(void); @@ -241,8 +247,6 @@ void EraseAllEntities(void) { gOAMControls.unk[1].unk6 = 1; } -extern Entity gUnk_030015A0[0x48]; - Entity* GetEmptyEntity() { u8 flags_ip; Entity* end; @@ -253,9 +257,9 @@ Entity* GetEmptyEntity() { LinkedList* listPtr; LinkedList* endListPtr; - if (gEntCount <= 0x46) { - currentEnt = gUnk_030015A0; - end = currentEnt + ARRAY_COUNT(gUnk_030015A0); + if (gEntCount < MAX_ENTITIES - 1) { + currentEnt = gEntities; + end = currentEnt + ARRAY_COUNT(gEntities); do { if (currentEnt->prev == 0) { @@ -267,7 +271,8 @@ Entity* GetEmptyEntity() { currentEnt = &gPlayerEntity; do { - if ((s32)currentEnt->prev < 0 && (currentEnt->flags & 0xc) && currentEnt != gUpdateContext.current_entity) { + if ((s32)currentEnt->prev < 0 && (currentEnt->flags & (ENT_UNUSED1 | ENT_UNUSED2)) && + currentEnt != gUpdateContext.current_entity) { ClearDeletedEntity(currentEnt); return currentEnt; } @@ -282,9 +287,10 @@ Entity* GetEmptyEntity() { currentEnt = listPtr->first; nextList = listPtr + 1; while ((u32)currentEnt != (u32)listPtr) { - if (currentEnt->kind != MANAGER && flags_ip < (currentEnt->flags & 0x1c) && + if (currentEnt->kind != MANAGER && + flags_ip < (currentEnt->flags & (ENT_UNUSED1 | ENT_UNUSED2 | ENT_DELETED)) && gUpdateContext.current_entity != currentEnt) { - flags_ip = currentEnt->flags & 0x1c; + flags_ip = currentEnt->flags & (ENT_UNUSED1 | ENT_UNUSED2 | ENT_DELETED); rv = currentEnt; } currentEnt = currentEnt->next; @@ -301,16 +307,16 @@ Entity* GetEmptyEntity() { return rv; } -extern Entity gItemGetEntities[7]; +extern Entity gAuxPlayerEntities[7]; -Entity* CreateItemGetEntity(void) { - Entity* ent = gItemGetEntities; +Entity* CreateAuxPlayerEntity(void) { + Entity* ent = gAuxPlayerEntities; do { if (ent->prev == NULL) { return ent; } - } while (++ent < &gItemGetEntities[7]); + } while (++ent < &gAuxPlayerEntities[7]); return NULL; } @@ -407,12 +413,6 @@ void DeleteAllEntities(void) { } } -typedef struct Temp { - void* prev; - void* next; - u8 _0[0x38]; -} Temp; - // fix this Manager* GetEmptyManager(void) { Temp* it; diff --git a/src/itemUtils.c b/src/itemUtils.c index 00cfd5e9..832c68ce 100644 --- a/src/itemUtils.c +++ b/src/itemUtils.c @@ -403,8 +403,8 @@ void EnableRandomDrops(void) { gRoomVars.randomDropsDisabled = FALSE; } -extern void sub_08000F14(s16*, const s16*, const s16*, const s16*); -extern u32 sub_08000F2C(s16*, const s16*, const s16*, const s16*); +extern void SumDropProbabilities(s16*, const s16*, const s16*, const s16*); +extern u32 SumDropProbabilities2(s16*, const s16*, const s16*, const s16*); u32 CreateItemDrop(Entity* arg0, u32 itemId, u32 itemParameter); u32 CreateRandomItemDrop(Entity* arg0, u32 arg1) { extern const u8 gUnk_080FE1B4[] /* = { @@ -459,7 +459,7 @@ u32 CreateRandomItemDrop(Entity* arg0, u32 arg1) { #endif } // vector addition, s0 = ptr4 + ptr2 + ptr3 - sub_08000F14(droptable.a, ptr4->a, ptr2->a, ptr3->a); + SumDropProbabilities(droptable.a, ptr4->a, ptr2->a, ptr3->a); if (gSave.stats.health <= 8) { droptable.s.hearts += 5; } @@ -486,7 +486,7 @@ u32 CreateRandomItemDrop(Entity* arg0, u32 arg1) { // vector addition, s0 = s0 + ptr2 + ptr3 // resulting values are clamped to be >= 0 // returns sum over s0 - summOdds = sub_08000F2C(droptable.a, droptable.a, ptr2->a, ptr3->a); + summOdds = SumDropProbabilities2(droptable.a, droptable.a, ptr2->a, ptr3->a); rand = Random(); item = (rand >> 0x18); item &= 0xF; diff --git a/src/object/gentariCurtain.c b/src/object/gentariCurtain.c index 14a25cea..bcfce42e 100644 --- a/src/object/gentariCurtain.c +++ b/src/object/gentariCurtain.c @@ -96,7 +96,7 @@ void sub_080921BC(GentariCurtainEntity* this) { GenericEntity* pEVar1; GenericEntity* end; - pEVar1 = (GenericEntity*)gItemGetEntities; + pEVar1 = (GenericEntity*)gAuxPlayerEntities; end = pEVar1 + 0x4f; do { diff --git a/src/objectUtils.c b/src/objectUtils.c index e3db7806..29e4deb8 100644 --- a/src/objectUtils.c +++ b/src/objectUtils.c @@ -31,7 +31,7 @@ const s8 gUnk_08126EEC[] = { }; Entity* CreateLinkAnimation(Entity* parent, u32 type, u32 type2) { - Entity* e = CreateItemGetEntity(); + Entity* e = CreateAuxPlayerEntity(); if (e != NULL) { LinkAnimationEntity* this = (LinkAnimationEntity*)e; e->id = LINK_ANIMATION; diff --git a/src/playerItemUtils.c b/src/playerItemUtils.c index b09ed736..6e7bb5f8 100644 --- a/src/playerItemUtils.c +++ b/src/playerItemUtils.c @@ -36,7 +36,7 @@ static Entity* GiveItemWithCutscene(u32 item, u32 type2, u32 delay) { item = ITEM_RUPEE50; type2 = 0; } - e = CreateItemGetEntity(); + e = CreateAuxPlayerEntity(); if (e != NULL) { e->type = item; e->type2 = type2; diff --git a/src/playerUtils.c b/src/playerUtils.c index 2cd630f7..9ab584e5 100644 --- a/src/playerUtils.c +++ b/src/playerUtils.c @@ -462,7 +462,7 @@ Entity* CreatePlayerItemWithParent(ItemBehavior* this, u32 id) { } void* CreateItemGetPlayerItemWithParent(ItemBehavior* this) { - GenericEntity* playerItem = (GenericEntity*)CreateItemGetEntity(); + GenericEntity* playerItem = (GenericEntity*)CreateAuxPlayerEntity(); if (playerItem != NULL) { playerItem->base.id = gItemDefinitions[this->behaviorId].playerItemId; playerItem->base.kind = PLAYER_ITEM; @@ -501,7 +501,7 @@ Entity* CreatePlayerItem(u32 id, u32 type, u32 type2, u32 unk) { Entity* sub_08077CF8(u32 id, u32 type, u32 type2, u32 unk) { GenericEntity* ent; - ent = (GenericEntity*)CreateItemGetEntity(); + ent = (GenericEntity*)CreateAuxPlayerEntity(); if (ent != NULL) { ent->base.flags = ENT_COLLIDE; ent->base.kind = PLAYER_ITEM; diff --git a/src/ui.c b/src/ui.c index 95a10ef4..b983b0b3 100644 --- a/src/ui.c +++ b/src/ui.c @@ -626,7 +626,8 @@ void ButtonUIElement_Action1(UIElement* element) { MAX_MOVEMENT = (!element->type2) ? 4 : 8; - if (element->type2 == 0 && (((gUnk_0200AF00.unk_1 >> element->type) & 1) || (gMessage.state & MESSAGE_ACTIVE) != 0)) { + if (element->type2 == 0 && + (((gUnk_0200AF00.unk_1 >> element->type) & 1) || (gMessage.state & MESSAGE_ACTIVE) != 0)) { y = (s16)gUnk_0200AF00.buttonY[element->type] - 0x28; } else { y = (s16)gUnk_0200AF00.buttonY[element->type];