diff options
| author | theo3 <arisstephenson2@gmail.com> | 2021-12-16 21:12:43 -0800 |
|---|---|---|
| committer | theo3 <arisstephenson2@gmail.com> | 2021-12-16 21:12:43 -0800 |
| commit | 28bf8b929fa13f89ce0a555fbcbb5545e4e4a88a (patch) | |
| tree | 95858e2f58fa2d8fae9db1d83f547b5e600ed780 /src | |
| parent | dc326a58d4aa675a4d968d4ea7a824ea33668298 (diff) | |
furniture ok
Diffstat (limited to 'src')
| -rw-r--r-- | src/object/furniture.c | 390 |
1 files changed, 390 insertions, 0 deletions
diff --git a/src/object/furniture.c b/src/object/furniture.c new file mode 100644 index 00000000..130c2ce4 --- /dev/null +++ b/src/object/furniture.c @@ -0,0 +1,390 @@ +#define NENT_DEPRECATED +#include "entity.h" +#include "room.h" +#include "functions.h" +#include "object.h" + +extern void sub_080001D0(u32, u32, u32); +extern u32 sub_080001DA(u32, u32); + +enum { + FURNITURE_INIT, + FURNITURE_UPDATE, +}; + +typedef enum { + TMP, +} FurnitureFlag; + +typedef enum { + TMP2, +} FurnitureType; + +typedef struct { + Entity base; + /* 0x68 */ u8 pad[0x10]; + /* 0x78 */ u16 tile; + /* 0x7a */ u16 unk1; + /* 0x7c */ u16 unk2; + /* 0x7e */ u16 unk3; + /* 0x80 */ u8 width; + /* 0x81 */ u8 height; + /* 0x82 */ u16 flags; +} FurnitureEntity; + +typedef void(FurnitureAction)(FurnitureEntity*); + +static FurnitureAction FurnitureInit; +static FurnitureAction FurnitureUpdate; + +typedef struct { + u8 width; + u8 height; + s8 x; + s8 y; + u8 rendering; + u8 priority; + u16 flags; +} FurnitureCfg; + +extern FurnitureCfg gUnk_08122128[]; +extern FurnitureCfg gUnk_08122198[]; +extern FurnitureCfg gUnk_081221A8[]; +extern FurnitureCfg gUnk_081221B8[]; +extern FurnitureCfg gUnk_081221C8[]; +extern FurnitureCfg gUnk_081221D8[]; +extern FurnitureCfg gUnk_081221E8[]; +extern FurnitureCfg gUnk_081221F8[]; +extern FurnitureCfg gUnk_08122208[]; +extern const FurnitureCfg gUnk_08121EF8[]; + +static void sub_08090DC4(FurnitureEntity*); +static void sub_08090E64(FurnitureEntity*); +static void sub_08090B6C(FurnitureEntity*); +static void sub_08090E4C(FurnitureEntity*); +static void sub_08090CDC(u32, u32, u32); + +void Furniture(FurnitureEntity* this) { + static FurnitureAction* const sFurnitureActions[] = { + FurnitureInit, + FurnitureUpdate, + }; + + sFurnitureActions[super->action](this); +} + +static void FurnitureInit(FurnitureEntity* this) { + u32 i, tile, cnt; + Entity* e; + + super->action = FURNITURE_UPDATE; + this->tile = COORD_TO_TILE(super); + sub_08090DC4(this); + switch (this->flags & 0x7fff) { + case 0x100: + super->collisionLayer = 2; + UpdateSpriteForCollisionLayer(super); + break; + case 0x20: + break; + case 0x40: + super->y.HALF.HI = (super->y.HALF.HI & ~0xF) | 4; + SetTile(0x4017, this->tile - 128, 1); + SetTile(0x4017, this->tile - 64, 1); + break; + case 0x80: + super->frameIndex = 0; + super->y.HALF.HI = (super->y.HALF.HI & ~0xF) | 6; + this->tile = COORD_TO_TILE(super); + SetTile(0x4026, this->tile, super->collisionLayer); + break; + case 0x200: + break; + case 0x400: + sub_08090E64(this); + if (super->type2 != 0) { + super->spriteOffsetX = 1; + this->width = 48; + } + default: + sub_08090B6C(this); + break; + } + + if (this->height != 16) { + switch (this->height & 0x70) { + case 0x30: + this->tile -= 64; + sub_08090B6C(this); + this->tile = COORD_TO_TILE(super); + case 0x20: + this->tile += 64; + sub_08090B6C(this); + } + this->tile = COORD_TO_TILE(super); + } + + switch (this->flags & 0x7fff) { + case 0x4: + ChangeObjPalette(super, 0x7E); + break; + case 0x2: + tile = this->tile - 129; + cnt = super->type != 26 ? 3 : 2; + for (i = 0; i < cnt; ++i, ++tile) { + SetTile(0x4026, tile, 2); + SetTile(0x4026, tile, 1); + sub_080001D0(0, tile + 64, 1); + } + break; + } + + switch (super->type) { + case 1: + if (super->type2 != 0) { + super->spritePriority.b0 = 4; + } + break; + case 9: + e = CreateObject(FURNITURE, 62, 0); + if (e != NULL) { + PositionRelative(super, e, 0x100000, 0x100000); + e->frameIndex = 1; + e->updatePriority = 2; + } + break; + case 30: + sub_0807B7D8(774, this->tile + 65, 2); + break; + case 31: + super->collisionLayer = 1; + super->spriteOrientation.flipY = 2; + SetTile(0x4074, this->tile - 64, super->collisionLayer); + sub_080001D0(63, this->tile - 64, super->collisionLayer); + SetTile(0x4017, this->tile, super->collisionLayer); + SetTile(0x4017, this->tile + 64, super->collisionLayer); + break; + case 40: + if (super->type2 != 0) + super->spriteOffsetX = -4; + break; + case 59: + SetTile(0x4023, this->tile - 65, super->collisionLayer); + SetTile(0x4023, this->tile - 64, super->collisionLayer); + SetTile(0x4023, this->tile - 63, super->collisionLayer); + break; + case 60: + SetTile(0x4022, this->tile + 65, super->collisionLayer); + } +} + +static void FurnitureUpdate(FurnitureEntity* this) { + switch (this->flags & 0x7FFF) { + case 0x1: + if (gPlayerEntity.y.HALF.HI < super->y.HALF.HI || gPlayerEntity.y.HALF.HI > super->y.HALF.HI + 24) { + super->spriteRendering.b3 = 2; + } else { + super->spriteRendering.b3 = 3; + } + break; + case 0x8: + if (++super->actionDelay == 16) { + super->actionDelay = 0; + super->field_0xf = (super->field_0xf + 1) & 3; + sub_08090E4C(this); + } + break; + case 0x10: + if (super->type != 62) { + if (++super->actionDelay == 20) { + super->frameIndex = (super->frameIndex + 1) & 3; + super->actionDelay = 0; + } + } else { + if (++super->actionDelay == 14) { + super->actionDelay = 0; + super->field_0xf = (super->field_0xf + 1) % 3; + super->frameIndex = super->field_0xf + 1; + } + } + break; + case 0x80: + if (gPlayerEntity.y.HALF.HI < super->y.HALF.HI + 8) { + if (gPlayerState.field_0x10[2] != 30 && GetTileTypeByEntity(super) == 0x4017) { + SetTile(0x4026, this->tile, super->collisionLayer); + SetTile(0x403D, this->tile - 64, super->collisionLayer); + SetTile(0x403D, this->tile - 128, super->collisionLayer); + } + } else { + if (gPlayerEntity.collisionLayer & 2) { + gPlayerEntity.collisionLayer = 1; + UpdateSpriteForCollisionLayer(&gPlayerEntity); + } + if (GetTileTypeByEntity(super) != 0x4017) { + SetTile(0x4017, this->tile, super->collisionLayer); + SetTile(0x4017, this->tile - 64, super->collisionLayer); + SetTile(0x4014, this->tile - 128, super->collisionLayer); + } + } + break; + } +} + +static void sub_08090B6C(FurnitureEntity* this) { + s32 num; + + u32 width = (u32)(this->width << 0x18) >> 0x18; + if (width != 0) { + u8 w2 = width / 8; + u32 px = super->x.HALF.HI & 0xF; + u32 tile = this->tile; + u32 cl = super->collisionLayer; + int i; + + switch ((u32)w2 & 3) { + case 0: + num = w2 / 8; + if (w2 == 0xc) { + num = 2; + } + for (i = -num; i <= num; ++i) { + SetTile(0x4022, tile + i, cl); + } + if (px & 8) { + sub_08090CDC(0x4024, tile - i, cl); + sub_08090CDC(0x4025, tile + i, cl); + } else { + SetTile(0x4022, tile - i, cl); + } + break; + case 1: + num = w2 / 8; + for (i = -num; i <= num; i++) { + SetTile(0x4022, tile + i, cl); + } + if (px & 8) { + sub_08090CDC(0x4024, tile - i, cl); + if (i != 0) { + SetTile(0x4022, tile + i, cl); + } + } else { + if (i != 0) { + SetTile(0x4022, tile - i, cl); + } + sub_08090CDC(0x4025, tile + i, cl); + } + break; + case 2: + num = w2 / 4; + for (i = -num; i < num; ++i) { + SetTile(0x4022, tile + i, cl); + } + if (px & 8) { + SetTile(0x4022, tile + i, cl); + } else { + sub_08090CDC(0x4024, tile - i - 1, cl); + sub_08090CDC(0x4025, tile + i, cl); + } + break; + case 3: + num = w2 / 4; + for (i = -num; i <= num; ++i) { + SetTile(0x4022, tile + i, cl); + } + if (px & 8) { + sub_08090CDC(0x4025, tile + i, cl); + } else { + sub_08090CDC(0x4024, tile - i, cl); + } + break; + } + } +} + +static void sub_08090CDC(u32 id, u32 pos, u32 layer) { + u16 cur = sub_080001DA(pos, layer); + u32 next = cur; + u32 id2; + + if ((cur & 0x4000) == 0) { + SetTile(id, pos, layer); + } else { + switch (cur) { + case 0x4025: + if (id == 0x4024) + next = 0x4022; + if (id == 0x402c) + next = 0x4022; + break; + case 0x402D: + if (id == 0x402c) + next = 0x402b; + if (id == 0x4024) + next = 0x4022; + break; + case 0x4024: + if (id == 0x4025) + next = 0x4022; + if (id == 0x402d) + next = 0x4022; + break; + case 0x402C: + if (id == 0x402d) + next = 0x402b; + if (id == 0x4025) + next = 0x4022; + break; + case 0x4022: + case 0x4023: + case 0x4026: + case 0x4027: + case 0x4028: + case 0x4029: + case 0x402a: + case 0x402b: + default: + return; + } + SetTile(next, pos, layer); + } +} + +static void sub_08090DC4(FurnitureEntity* this) { + static const FurnitureCfg* const sCfgTable[] = { + gUnk_08122128, gUnk_08122198, gUnk_081221A8, gUnk_081221B8, gUnk_081221C8, + gUnk_081221D8, gUnk_081221E8, gUnk_081221F8, gUnk_08122208, + }; + + const FurnitureCfg* cfg = &gUnk_08121EF8[super->type]; + if (cfg->flags & 0x8000) { + cfg = sCfgTable[cfg->y]; + cfg += super->type2; + super->frameIndex = super->type2; + } + this->width = cfg->width; + this->height = cfg->height; + super->spriteOffsetX = cfg->x; + super->spriteOffsetY = cfg->y; + super->spriteRendering.b3 = cfg->rendering; + super->spritePriority.b0 = cfg->priority; + this->flags = cfg->flags; +} + +static void sub_08090E4C(FurnitureEntity* this) { + static const u32 sPalettes[] = { 0x5f, 0x60, 0x61, 0x62 }; + + ChangeObjPalette(super, sPalettes[super->field_0xf]); +} + +static NONMATCH("asm/non_matching/furniture/sub_08090E64.s", void sub_08090E64(FurnitureEntity* this)) { + Entity* e = CreateObject(OBJECT_42, 0, 0); + u32 tmp = 0x10000 - 2; + + if (e != NULL) { + PositionRelative(super, e, (tmp + super->type2) * 0x10000, 0); + e->z.HALF.HI -= 16; + e->collisionLayer = 2; + UpdateSpriteForCollisionLayer(e); + } +} +END_NONMATCH |
