diff --git a/include/common_structs.h b/include/common_structs.h index fe6fabcfe5..8f9fc6c609 100644 --- a/include/common_structs.h +++ b/include/common_structs.h @@ -511,7 +511,7 @@ typedef union { struct SpinningFlowerData* spinningFlower; struct TrumpetPlantData* trumpetPlant; struct MunchlesiaData* munchlesia; - struct ArrowSignData* arrowSign; + struct ArrowSignData* arrowSign; } EntityData; typedef struct Entity { diff --git a/include/effects.h b/include/effects.h index bffd278318..3e38629f6c 100644 --- a/include/effects.h +++ b/include/effects.h @@ -239,7 +239,7 @@ typedef struct FlowerFXData { typedef struct CloudPuffFXData { /* 0x00 */ s32 alive; /* 0x04 */ char unk_04[0x2]; - /* 0x06 */ s16 lifetime; + /* 0x06 */ s16 timeLeft; /* 0x08 */ u8 alpha; /* 0x09 */ char unk_09[0x3]; /* 0x0C */ f32 unk_0C; @@ -332,9 +332,7 @@ typedef struct FloatingFlowerFXData { } FloatingFlowerFXData; // size = 0x48 typedef struct SnowflakeFXData { - /* 0x00 */ f32 xPos; - /* 0x04 */ f32 yPos; - /* 0x08 */ f32 zPos; + /* 0x00 */ Vec3f pos; /* 0x0C */ f32 unk_0C; /* 0x10 */ f32 unk_10; /* 0x14 */ f32 unk_14; @@ -641,8 +639,8 @@ typedef struct FireBreathFXData { /* 0x38 */ f32 scale; /* 0x3C */ f32 scaleChangeFactor; /* 0x40 */ s32 alpha; - /* 0x44 */ s32 maxLifetime; - /* 0x48 */ s32 lifetime; + /* 0x44 */ s32 lifeTime; + /* 0x48 */ s32 timeLeft; /* 0x4C */ s32 spawnTimer; /* 0x50 */ Vec3f unk_50; /* 0x5C */ f32 unk_5C; @@ -766,8 +764,20 @@ typedef struct DisableXFXData { } DisableXFXData; // size = 0x48 typedef struct BombetteBreakingFXData { - /* 0x00 */ char todo[0]; -} BombetteBreakingFXData; // size = unknown + /* 0x00 */ s16 type; + /* 0x02 */ s16 treeIndex; + /* 0x04 */ f32 unk_04; + /* 0x08 */ Vec3f center; + /* 0x14 */ Vec3f unk_14; + /* 0x20 */ Vec3f unk_20; + /* 0x2C */ Vec3f unk_2C; + /* 0x38 */ f32 unk_38; + /* 0x3C */ f32 unk_3C; + /* 0x40 */ f32 unk_40; + /* 0x44 */ s32 timeLeft; + /* 0x48 */ s32 unk_48; + /* 0x4C */ s32 alpha; +} BombetteBreakingFXData; typedef struct FireworkFXData { /* 0x00 */ char todo[0]; @@ -1240,7 +1250,21 @@ typedef struct SomethingRotatingFXData { } SomethingRotatingFXData; // size = unknown typedef struct BreakingJunkFXData { - /* 0x00 */ char todo[0]; + /* 0x00 */ s32 unk_00; + /* 0x04 */ Vec3f pos; + /* 0x10 */ Vec3f vel; + /* 0x1C */ s32 timeLeft; + /* 0x20 */ s32 lifeTime; + /* 0x24 */ f32 scale; + /* 0x28 */ f32 rot; + /* 0x2C */ s16 primR; + /* 0x2E */ s16 primG; + /* 0x30 */ s16 primB; + /* 0x32 */ s16 primA; + /* 0x34 */ s16 envR; + /* 0x36 */ s16 envG; + /* 0x38 */ s16 envB; + /* 0x3A */ s16 envA; } BreakingJunkFXData; // size = unknown typedef struct PartnerBuffFXData { @@ -1470,8 +1494,8 @@ typedef struct WattEffectData { /* 0x08 */ s32 angle; /* 0x0C */ s32 unk_0C; /* 0x10 */ s32 unk_10; - /* 0x14 */ struct EffectInstance* effect1; - /* 0x18 */ struct EffectInstance* effect2; + /* 0x14 */ EffectInstance* effect1; + /* 0x18 */ EffectInstance* effect2; /* 0x1C */ s32 debuff; } WattEffectData; diff --git a/include/effects_internal.h b/include/effects_internal.h index 2138a54f86..3e505b2ce4 100644 --- a/include/effects_internal.h +++ b/include/effects_internal.h @@ -29,6 +29,7 @@ void shim_mem_clear(void* data, s32 numBytes); void shim_transform_point(Matrix4f mtx, f32 inX, f32 inY, f32 inZ, f32 inS, f32* outX, f32* outY, f32* outZ, f32* outS); s32 shim_npc_raycast_down_sides(s32, f32*, f32*, f32*, f32*); void shim_sfx_play_sound_at_position(s32 soundID, s32 value2, f32 posX, f32 posY, f32 posZ); +void shim_mdl_draw_hidden_panel_surface(Gfx**, u16 treeIndex); // the actual signature is going to be wrong, but it doesn't matter // TODO remove when every effect's main is sorted out @@ -94,7 +95,7 @@ void blast_main(s32, f32, f32, f32, f32, s32); EffectInstance* fire_flower_main(s32, f32, f32, f32, s32); FX_MAIN(recover_main); EffectInstance* disable_x_main(s32, f32, f32, f32, s32); -FX_MAIN(bombette_breaking_main); +EffectInstance* bombette_breaking_main(s32, s32, s32, f32, s32, s32); FX_MAIN(firework_main); FX_MAIN(confetti_main); FX_MAIN(snowfall_main); @@ -152,7 +153,7 @@ FX_MAIN(ice_shard_main); FX_MAIN(spirit_card_main); FX_MAIN(lil_oink_main); FX_MAIN(something_rotating_main); -FX_MAIN(breaking_junk_main); +EffectInstance* breaking_junk_main(s32 arg0, f32 arg1, f32 arg2, f32 arg3, f32 arg4, s32 arg5); FX_MAIN(partner_buff_main); FX_MAIN(quizmo_assistant_main); FX_MAIN(ice_pillar_main); diff --git a/include/macros.h b/include/macros.h index 101c6c6afd..2271973846 100644 --- a/include/macros.h +++ b/include/macros.h @@ -13,6 +13,7 @@ #endif #define ALIGN16(val) (((val) + 0xF) & ~0xF) +#define ALIGN8(val) (((val) + 0x7) & ~0x7) #define A(sym) NS(AREA, sym) #define N(sym) NS(NAMESPACE, sym) diff --git a/src/101b90_len_8f0.c b/src/101b90_len_8f0.c index c9fcd7284d..743427fa66 100644 --- a/src/101b90_len_8f0.c +++ b/src/101b90_len_8f0.c @@ -5,18 +5,98 @@ // TODO generate this somehow, or prevent it from shifting. must be resolved at compile time #define SPRITE_ROM_START 0x1943000 + 0x10 +extern s32 spr_allocateBtlComponentsOnWorldHeap; +extern s32 D_802DFEB0[]; +extern s32 D_802DFEB8[]; extern s32 PlayerRasterSetsLoaded; extern s32 PlayerRasterBufferSetOffsets[13]; +extern s32 D_802E0090[]; extern s32 PlayerRasterHeader; +extern s32 D_802E0C14[]; extern s32 D_802E0C20[]; extern s32 PlayerRasterCacheSize; extern s32 PlayerRasterMaxSize; extern s32 SpriteDataHeader[]; +extern s32 D_802E0C64; +extern s32 D_802E0C68; extern PlayerSpriteCacheEntry PlayerRasterCache[18]; INCLUDE_ASM(s32, "101b90_len_8f0", spr_swizzle_anim_offsets); +#ifdef NON_EQUIVALENT +SpriteAnimData* spr_load_sprite(s32 idx, s32 arg1, s32 arg2) { + SpriteAnimData* animData; + s32 base; + s32 i; + + s32 temp_s0; + s32 temp_s0_2; + s32 temp_v0_2; + s32 temp_v0_3; + s32* temp_a1_3; + s32** var_s2; + u16** var_v1; + s32* temp_v0; + + if (arg1) { + base = D_802E0C64; + } else { + base = D_802E0C68; + } + nuPiReadRom(base + (idx * 4), &D_802DFEB0, 8U); + + temp_s0 = ALIGN8(D_802DFEB0[1] - D_802DFEB0[0]); + temp_v0 = general_heap_malloc(temp_s0); + nuPiReadRom(base + D_802DFEB0[0], temp_v0, temp_s0); + + if (arg2) { + temp_v0++; + animData = _heap_malloc_tail(&gSpriteHeapPtr, *temp_v0); + } else { + temp_v0++; + animData = _heap_malloc(&gSpriteHeapPtr, *temp_v0); + } + + decode_yay0(temp_v0, animData); + general_heap_free(temp_v0); + + temp_v0_2 = ((u32) animData / 4) * 4; + var_s2 = animData->rastersOffset + temp_v0_2; + animData->rastersOffset = var_s2; + + while (*var_s2 != (s32* )-1) { + temp_a1_3 = *var_s2 + temp_v0_2; + *var_s2 = temp_a1_3; + var_s2++; + if (!arg1) { + *temp_a1_3 += temp_v0_2; + } + } + + if (arg1) { + D_802E0050[idx] = D_802E004C; + temp_s0_2 = D_802E0C20[idx + 1] - D_802E0C20[idx]; + nuPiReadRom(D_802E0C60[0] + D_802E0C14[0] + D_802E0C20[idx], &D_802DFEB8, 0x194); + for (i = 0; i < temp_s0_2; i++) { + D_802E0090[D_802E004C++] = D_802DFEB8[i]; + } + } + + temp_v0_3 = ((u32) animData / 4) * 4; + var_v1 = animData->palettesOffset + temp_v0_3; + animData->palettesOffset = var_v1; + + while (*var_v1 != -1) { + *var_v1 += temp_v0_3; + var_v1++; + } + + spr_swizzle_anim_offsets(0, 0, animData); + return animData; +} +#else INCLUDE_ASM(s32, "101b90_len_8f0", spr_load_sprite); +#endif void spr_init_player_raster_cache(s32 cacheSize, s32 maxRasterSize) { void* raster; @@ -46,7 +126,35 @@ void spr_init_player_raster_cache(s32 cacheSize, s32 maxRasterSize) { nuPiReadRom(SpriteDataHeader[0] + PlayerRasterHeader, D_802E0C20, 0x38); } -INCLUDE_ASM(s32, "101b90_len_8f0", spr_get_player_raster); +IMG_PTR spr_get_player_raster(s32 rasterIndex, s32 playerSpriteID) { + PlayerSpriteCacheEntry* temp_s0; + u32 temp_a2; + s32 idx = -1; + s32 i; + + for (i = 0; i < PlayerRasterCacheSize; i++) { + if (PlayerRasterCache[i].lazyDeleteTime != 0) { + if (PlayerRasterCache[i].rasterIndex == rasterIndex && PlayerRasterCache[i].spriteIndex == playerSpriteID) { + PlayerRasterCache[i].lazyDeleteTime = 2; + return PlayerRasterCache[i].raster; + } + } else if (idx == -1) { + idx = i; + } + } + + if (idx == -1) { + return NULL; + } + + temp_s0 = &PlayerRasterCache[idx]; + temp_s0->rasterIndex = rasterIndex; + temp_s0->spriteIndex = playerSpriteID; + temp_s0->lazyDeleteTime = 2; + temp_a2 = D_802E0090[PlayerRasterBufferSetOffsets[playerSpriteID] + rasterIndex]; + nuPiReadRom(*SpriteDataHeader + (temp_a2 & 0xFFFFF), temp_s0->raster, (temp_a2 >> 0x10) & 0xFFF0); + return temp_s0->raster; +} void spr_update_player_raster_cache(void) { s32 i; @@ -62,4 +170,36 @@ void spr_update_player_raster_cache(void) { INCLUDE_ASM(s32, "101b90_len_8f0", spr_load_npc_extra_anims); +#ifdef NON_MATCHING +void** spr_allocate_components(s32 arg0) { + s32 temp_s1; + void** heap; + void* var_a0_2; + void** new_var; + u32 size; + s32 i; + + temp_s1 = (arg0 + 1) * 4; + size = (arg0 * 0x50) + (temp_s1); + + if (spr_allocateBtlComponentsOnWorldHeap) { + heap = _heap_malloc(&heap_generalHead, size); + } else { + heap = _heap_malloc(&gSpriteHeapPtr, size); + } + + new_var = heap; + + var_a0_2 = heap + (temp_s1 / 4); + + for (i = 0; i < arg0; i++) { + *new_var = var_a0_2; + new_var++; + var_a0_2 += 0x50; + } + *new_var = (void* )-1; + return heap; +} +#else INCLUDE_ASM(s32, "101b90_len_8f0", spr_allocate_components); +#endif diff --git a/src/168590.c b/src/168590.c index 037e58ccae..c5c40f9a56 100644 --- a/src/168590.c +++ b/src/168590.c @@ -2,8 +2,20 @@ #include "filemenu.h" #include "hud_element.h" +typedef struct UnkStruct8015A370 { + /* 0x00 */ u8 unk_00; + /* 0x01 */ char unk_01[0x3]; + /* 0x04 */ void (*unk_04)(s32); + /* 0x08 */ char unk_08[0x14]; + /* 0x1C */ u8 unk_1C; +} UnkStruct8015A370; + +extern UnkStruct8015A370 D_8015A370; + extern MenuWindowBP D_8024A134[1]; extern HudScript* D_8024A180[3]; +extern s32 D_8024A18C; +extern s32 D_8024C108; extern MenuWindowBP D_8024A190[2]; extern s32 D_8024A1B4; extern s8 D_8024C090; @@ -128,7 +140,149 @@ void filemenu_draw_contents_file_create_header(MenuPanel* menu, s32 baseX, s32 b } void filemenu_draw_contents_choose_name(MenuPanel* menu, s32 baseX, s32 baseY, s32 width, s32 height, s32 opacity, s32 darkening); + +#ifdef NON_MATCHING +void filemenu_draw_contents_choose_name(MenuPanel* menu, s32 baseX, s32 baseY, s32 width, s32 height, s32 opacity, + s32 darkening) +{ + s32 sp18; + s32 menuPage; + s32 pageNotOne; + s32 page; + s32 temp_s2; + s32 new_var; + + s32 gridData; + s32 xOffset; + s32 yOffset; + s32 color; + s32 flags; + s32 i; + s32 r; + s32 c; + + s32 new_var2; + + if ((D_8015A370.unk_00 & 8) && D_8015A370.unk_04 == func_80248170) { + sp18 = D_8015A370.unk_1C * 2; + menuPage = menu->page; + pageNotOne = menu->page != 1; + if (sp18 > 0x10) { + sp18 = 0x10; + } + + for (r = 0; r < menu->numRows; r++) { + temp_s2 = (r * 15); // ??? + + for (i = 0; i < 2; i++) { + if (i == 0) { + temp_s2 += 4; + page = menuPage; + gDPSetScissor(gMasterGfxPos++, G_SC_NON_INTERLACE, + baseX, + baseY + temp_s2, + baseX + width, + baseY + temp_s2 + sp18); + } else { + temp_s2 += 4; + page = pageNotOne; + gDPSetScissor(gMasterGfxPos++, G_SC_NON_INTERLACE, + baseX, + baseY + temp_s2 + sp18, + baseX + width, + baseY + temp_s2 + 0x10); + } + + for (c = 0; c < menu->numCols; c++) { + gridData = menu->gridData[(page * menu->numCols * menu->numRows) + (menu->numCols * r) + c]; + if (gridData != 0xF7) { + if (r == menu->col && c == menu->row) { + flags = 8; + color = 0; + } else { + flags = 0; + color = 10; + } + xOffset = (c * 19) + 12; + yOffset = (r * 17) + 5; + if ((u32) (gridData - 0xA2) < 0x4EU) { + if (gridData >= 0xC6) { + hud_element_set_render_pos(D_8024C108, baseX + xOffset + 22, baseY + yOffset + 8); + hud_element_draw_without_clipping(D_8024C108); + flags = 0; + } + } + if (gridData == 0xC6) { + xOffset -= 1; + } + if (gridData == 0xC9) { + xOffset += 5; + } + if (gridData == 0xCA) { + xOffset += 8; + } + if (gridData == 0xC6 || gridData == 0xCA || gridData == 0xC9) { + yOffset -= 1; + } + filemenu_draw_message((Message* ) gridData, baseX + xOffset, baseY + yOffset, 255, color, flags); + } + } + } + } + gDPSetScissor(gMasterGfxPos++, G_SC_NON_INTERLACE, baseX, baseY, baseX + width, baseY + height); + } else { + for (r = 0; r < menu->numCols; r++) { + for (c = 0; c < menu->numRows; c++) { + gridData = menu->gridData[(menu->page * menu->numCols * menu->numRows) + (menu->numCols * c) + r]; + if (gridData != 0xF7) { + if (r == menu->col && c == menu->row) { + flags = 8; + color = 0; + } else { + flags = 0; + color = 10; + } + xOffset = (r * 19) + 12; + yOffset = (c * 17) + 5; + + new_var2 = gridData; // ??? + + if ((u32) (gridData - 0xA2) < 0x4EU) { + if (gridData >= 0xC6) { + hud_element_set_render_pos(D_8024C108, baseX + xOffset + 22, baseY + yOffset + 8); + hud_element_draw_without_clipping(D_8024C108); + flags = 0; + } + } + if (gridData == 0xC6) { + xOffset -= 1; + } + if (gridData == 0xC9) { + xOffset += 5; + } + if (gridData == 0xCA) { + xOffset += 8; + } + if (gridData == 0xC6 || gridData == 0xCA || gridData == 0xC9) { + yOffset -= 1; + } + filemenu_draw_message((Message* ) new_var2, baseX + xOffset, baseY + yOffset, 255, color, flags); + } + } + } + } + + if (filemenu_8024C098 == 3) { + if (filemenu_heldButtons & (BUTTON_STICK_RIGHT | BUTTON_STICK_LEFT | BUTTON_STICK_DOWN | BUTTON_STICK_UP)) { + D_8024A18C = -4; + } + D_8024A18C += 1; + filemenu_set_cursor_goal_pos(0x31, baseX + 2 + (menu->col * 19), baseY + 13 + (menu->row * 17)); + } +} +#else INCLUDE_ASM(s32, "168590", filemenu_draw_contents_choose_name); +#endif void filemenu_choose_name_init(MenuPanel* menu) { s32 i; diff --git a/src/16F740.c b/src/16F740.c index dc80cb8115..98c74999f8 100644 --- a/src/16F740.c +++ b/src/16F740.c @@ -184,7 +184,176 @@ void btl_state_draw_normal_start(void) { } } -INCLUDE_ASM(s32, "16F740", btl_state_update_begin_turn); +void btl_state_update_begin_turn(void) { + BattleStatus* battleStatus = &gBattleStatus; + PlayerData* playerData = &gPlayerData; + Actor* partner = battleStatus->partnerActor; + Actor* player = battleStatus->playerActor; + Actor* enemy; + Actor* enemy1; + Actor* enemy2; + Evt* script; + Evt* script2; + s32 cond; + u16 id1; + u16 id2; + s32 numEnemyActors; + s32 i; + s32 j; + s16* enemyIDs; + + if (gBattleState2 == 0) { + battleStatus->flags2 &= ~BS_FLAGS2_2; + battleStatus->flags2 &= ~BS_FLAGS2_4; + battleStatus->flags2 &= ~BS_FLAGS2_8; + battleStatus->flags2 &= ~BS_FLAGS2_10; + battleStatus->merleeAttackBoost = 0; + battleStatus->merleeDefenseBoost = 0; + battleStatus->flags2 &= ~BS_FLAGS2_1000000; + player->unk_21D = 0; + player->flags |= ACTOR_FLAG_8000000 | ACTOR_FLAG_4000000; + if (partner != NULL) { + player->flags |= ACTOR_FLAG_8000000 | ACTOR_FLAG_4000000; + partner->unk_21D = 0; + } + + if (battleStatus->hustleTurns != 0) { + battleStatus->flags1 |= BS_FLAGS1_4000000; + } + + numEnemyActors = 0; + for (i = 0; i < ARRAY_COUNT(battleStatus->enemyActors); i++) { + enemy = battleStatus->enemyActors[i]; + if (enemy != NULL) { + battleStatus->enemyIDs[numEnemyActors] = i | ACTOR_ENEMY0; + numEnemyActors++; + } + } + + battleStatus->numEnemyActors = numEnemyActors; + enemyIDs = battleStatus->enemyIDs; + for (i = 0; i < numEnemyActors - 1; i++) { + for (j = i + 1; j < numEnemyActors; j++) { + id1 = enemyIDs[i]; + id2 = enemyIDs[j]; + enemy1 = battleStatus->enemyActors[id1 & 0xFF]; + enemy2 = battleStatus->enemyActors[id2 & 0xFF]; + if (gBattleStatus.flags1 & BS_FLAGS1_8000000) { + if (enemy1->homePos.x > enemy2->homePos.x) { + enemyIDs[i] = id2; + enemyIDs[j] = id1; + } + } else if (enemy1->turnPriority < enemy2->turnPriority) { + enemyIDs[i] = id2; + enemyIDs[j] = id1; + } + } + } + + battleStatus->nextEnemyIndex = 0; + btl_merlee_on_start_turn(); + battleStatus->rushFlags = 0; + gBattleStatus.flags2 &= ~BS_FLAGS2_8000000; + + if (!(gBattleStatus.flags2 & BS_FLAGS2_40)) { + if (playerData->curHP < 2 && is_ability_active(ABILITY_MEGA_RUSH)) { + gBattleStatus.flags2 |= BS_FLAGS2_8000000; + battleStatus->rushFlags |= 1; + } + if (playerData->curHP < 6 && is_ability_active(ABILITY_POWER_RUSH) && !(battleStatus->rushFlags & 1)) { + gBattleStatus.flags2 |= BS_FLAGS2_8000000; + battleStatus->rushFlags |= 2; + } + } + + if (!(gBattleStatus.flags1 & BS_FLAGS1_20000000)) { + battleStatus->jumpCharge = 0; + } + + if (!(gBattleStatus.flags1 & BS_FLAGS1_10000000)) { + battleStatus->hammerCharge = 0; + } + + if (gGameStatusPtr->debugEnemyContact == 4) { + btl_set_state(BATTLE_STATE_RUN_AWAY); + return; + } + + if (gGameStatusPtr->debugEnemyContact == 3) { + for (i = 0; i < ARRAY_COUNT(battleStatus->enemyActors); i++) { + enemy = battleStatus->enemyActors[i]; + if (enemy != NULL && enemy->onHitScriptSource != NULL) { + Evt* script = start_script(enemy->onHitScriptSource, 0xA, 0); + + enemy->onHitScript = script; + script->owner1.actorID = i | ACTOR_ENEMY0; + enemy->onHitID = script->id; + enemy->lastEventType = EVENT_DEATH; + } + } + gBattleState2 = BATTLE_STATE_SWITCH_TO_PLAYER; + } else { + for (i = 0; i < ARRAY_COUNT(battleStatus->enemyActors); i++) { + enemy = battleStatus->enemyActors[i]; + if (enemy != NULL && enemy->onTurnChanceScriptSource != NULL) { + battleStatus->battlePhase = PHASE_PLAYER_BEGIN; + script = start_script(enemy->onTurnChanceScriptSource, 0xA, 0); + enemy->onTurnChangeScript = script; + enemy->onTurnChangeID = script->id; + script->owner1.actorID = i | ACTOR_ENEMY0; + } + } + + partner = battleStatus->partnerActor; + if (partner != NULL) { + if (partner->onTurnChanceScriptSource != NULL) { + battleStatus->battlePhase = PHASE_PLAYER_BEGIN; + script = start_script(partner->onTurnChanceScriptSource, 0xA, 0); + partner->onTurnChangeScript = script; + partner->onTurnChangeID = script->id; + script->owner1.actorID = ACTOR_PARTNER; + } + } + gBattleState2 = BATTLE_STATE_BEGIN_TURN; + } + } + + if (gBattleState2 == BATTLE_STATE_BEGIN_TURN) { + cond = FALSE; + for (i = 0; i < ARRAY_COUNT(battleStatus->enemyActors); i++) { + enemy = battleStatus->enemyActors[i]; + if (enemy != NULL && enemy->onTurnChanceScriptSource != NULL && does_script_exist(enemy->onTurnChangeID)) { + cond = TRUE; + } + } + if (partner != NULL && partner->onTurnChanceScriptSource != NULL && does_script_exist(partner->onTurnChangeID)) { + cond = TRUE; + } + + if (!cond) { + if (!btl_check_enemies_defeated()) { + btl_set_state(BATTLE_STATE_BEGIN_PLAYER_TURN); + } + return; + } + } + + if (gBattleState2 == BATTLE_STATE_SWITCH_TO_PLAYER) { + cond = FALSE; + for (i = 0; i < ARRAY_COUNT(battleStatus->enemyActors); i++) { + enemy = battleStatus->enemyActors[i]; + if (enemy != NULL && enemy->onHitScriptSource != NULL && does_script_exist(enemy->onHitID)) { + cond = TRUE; + } + } + + if (!cond) { + if (!btl_check_enemies_defeated()) { + btl_set_state(BATTLE_STATE_BEGIN_PLAYER_TURN); + } + } + } +} void btl_state_draw_begin_turn(void) { } diff --git a/src/17D6A0.c b/src/17D6A0.c index fabd8beefe..bcd3409efe 100644 --- a/src/17D6A0.c +++ b/src/17D6A0.c @@ -5,11 +5,46 @@ #include "hud_element.h" s16 D_80280FC0[] = { - 10, 90, 0, 50, 3, 11, 0, 50, 1, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, - 1, 49, 0, 50, 1, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 1, 50, 0, 50, 1, - 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 3, 10, 0, 50, 3, 10, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 3, 10, 0, 20, 3, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 10, 90, 0, 50, + 3, 11, 0, 50, + 1, 45, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 50, + 1, 49, 0, 50, + 1, 49, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 50, + 1, 50, 0, 50, + 1, 50, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 50, + 3, 10, 0, 50, + 3, 10, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 80, + 3, 10, 0, 20, + 3, 11, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, }; s32 bActorNames[ACTOR_TYPE_COUNT] = { diff --git a/src/190B20.c b/src/190B20.c index 80814b93e2..eb508034a2 100644 --- a/src/190B20.c +++ b/src/190B20.c @@ -220,7 +220,7 @@ s32 btl_are_all_enemies_defeated(void) { s32 btl_check_enemies_defeated(void) { if (btl_are_all_enemies_defeated()) { - btl_set_state(0x1A); + btl_set_state(BATTLE_STATE_VICTORY); return TRUE; } return FALSE; diff --git a/src/effects.c b/src/effects.c index 5f13841248..8619d63360 100644 --- a/src/effects.c +++ b/src/effects.c @@ -102,7 +102,7 @@ EffectTableEntry gEffectTable[] = { /* 0x48 */ FX_ENTRY(attack_result_text, _3903D0), /* 0x49 */ FX_ENTRY(small_gold_sparkle, effect_gfx_small_gold_sparkle), /* 0x4A */ FX_ENTRY(flashing_box_shockwave, _3930A0), - /* 0x4B */ FX_ENTRY(balloon, _394670), + /* 0x4B */ FX_ENTRY(balloon, effect_gfx_balloon), /* 0x4C */ FX_ENTRY(floating_rock, _3960F0), /* 0x4D */ FX_ENTRY(chomp_drop, _397040), /* 0x4E */ FX_ENTRY(quizmo_stage, _398BC0), @@ -122,7 +122,7 @@ EffectTableEntry gEffectTable[] = { /* 0x5C */ FX_ENTRY(water_fountain, _3B8860), /* 0x5D */ FX_ENTRY(underwater, _3B9A70), /* 0x5E */ FX_ENTRY(lightning_bolt, _3BAEA0), - /* 0x5F */ FX_ENTRY(water_splash, _3BCA90), + /* 0x5F */ FX_ENTRY(water_splash, effect_gfx_water_splash), /* 0x60 */ FX_ENTRY(snowman_doll, _3BD9A0), /* 0x61 */ FX_ENTRY(fright_jar, _3C1BA0), /* 0x62 */ FX_ENTRY(stop_watch, _3CB890), @@ -153,7 +153,7 @@ EffectTableEntry gEffectTable[] = { /* 0x7B */ FX_ENTRY(spirit_card, _3FA4B0), /* 0x7C */ FX_ENTRY(lil_oink, _3FF250), /* 0x7D */ FX_ENTRY(something_rotating, _3FA4B0), - /* 0x7E */ FX_ENTRY(breaking_junk, _403BF0), + /* 0x7E */ FX_ENTRY(breaking_junk, effect_gfx_breaking_junk), /* 0x7F */ FX_ENTRY(partner_buff, _404F40), /* 0x80 */ FX_ENTRY(quizmo_assistant, _407080), /* 0x81 */ FX_ENTRY(ice_pillar, _40A1C0), diff --git a/src/effects/balloon.c b/src/effects/balloon.c index 055706c116..3b1f4ffda6 100644 --- a/src/effects/balloon.c +++ b/src/effects/balloon.c @@ -1,12 +1,12 @@ #include "common.h" #include "effects_internal.h" -extern Gfx D_09001280[]; -extern Gfx D_09001358[]; -extern Gfx D_09001430[]; -extern Gfx D_09001508[]; +extern Gfx D_09001280_3958F0[]; +extern Gfx D_09001358_3959C8[]; +extern Gfx D_09001430_395AA0[]; +extern Gfx D_09001508_395B78[]; -Gfx* D_E00963E0[] = { D_09001280, D_09001358, D_09001430 }; +Gfx* D_E00963E0[] = { D_09001280_3958F0, D_09001358_3959C8, D_09001430_395AA0 }; void balloon_init(EffectInstance* effect); void balloon_update(EffectInstance* effect); @@ -102,7 +102,7 @@ void balloon_appendGfx(void* effect) { gSPMatrix(gMasterGfxPos++, &gDisplayContext->matrixStack[gMatrixListPos++], G_MTX_PUSH | G_MTX_MUL | G_MTX_MODELVIEW); gSPDisplayList(gMasterGfxPos++, D_E00963E0[idx]); - gSPDisplayList(gMasterGfxPos++, D_09001508); + gSPDisplayList(gMasterGfxPos++, D_09001508_395B78); gSPPopMatrix(gMasterGfxPos++, G_MTX_MODELVIEW); gDPPipeSync(gMasterGfxPos++); } diff --git a/src/effects/blast.c b/src/effects/blast.c index 5a1bdc553e..b6283a8cf3 100644 --- a/src/effects/blast.c +++ b/src/effects/blast.c @@ -1,12 +1,27 @@ #include "common.h" #include "effects_internal.h" - void blast_init(EffectInstance* effect); void blast_update(EffectInstance* effect); void blast_render(EffectInstance* effect); void blast_appendGfx(void* effect); +extern Gfx D_09001300[]; +extern Gfx D_09001378[]; +extern Gfx D_090013F0[]; +extern Gfx D_09001468[]; +extern Gfx D_090014E0[]; +extern Gfx D_09001558[]; +extern Gfx D_090015D0[]; +extern Gfx D_09001648[]; +extern Gfx D_090016C0[]; +extern Gfx D_09001738[]; +extern Gfx D_090017B0[]; + +Gfx* D_E007C510[] = { + D_09001378, D_090013F0, D_09001468, D_090014E0, D_09001558, D_090015D0, D_09001648, D_090016C0, D_09001738 +}; + void blast_main(s32 arg0, f32 arg1, f32 arg2, f32 arg3, f32 arg4, s32 arg5) { EffectBlueprint bp; EffectBlueprint* bpPtr = &bp; @@ -75,4 +90,50 @@ void blast_render(EffectInstance* effect) { retTask->renderMode |= RENDER_TASK_FLAG_2; } +#ifdef NON_MATCHING +void blast_appendGfx(void* effect) { + Matrix4f sp18, sp58, sp98; + Gfx* dlist; + Gfx* dlist2; + BlastFXData* data = ((EffectInstance*)effect)->data; + f32 temp_f2; + s32 temp_f4; + s32 alpha; + + dlist = D_090017B0; + dlist2 = D_09001300; + + temp_f4 = data->unk_20; + temp_f2 = temp_f4; + alpha = (temp_f2 - temp_f4) * 256.0f; + + gDPPipeSync(gMasterGfxPos++); + gSPSegment(gMasterGfxPos++, 0x09, VIRTUAL_TO_PHYSICAL(((EffectInstance*)effect)->graphics->data)); + gSPDisplayList(gMasterGfxPos++, dlist2); + gSPDisplayList(gMasterGfxPos++, D_E007C510[temp_f4]); + + shim_guTranslateF(sp18, data->pos.x, data->pos.y, data->pos.z); + shim_guRotateF(sp58, -gCameras[gCurrentCameraID].currentYaw, 0.0f, 1.0f, 0.0f); + shim_guMtxCatF(sp58, sp18, sp98); + shim_guScaleF(sp18, data->unk_10, data->unk_10, 1.0f); + shim_guMtxCatF(sp18, sp98, sp98); + shim_guRotateF(sp18, data->unk_24, 0.0f, 0.0f, 1.0f); + shim_guMtxCatF(sp18, sp98, sp98); + shim_guMtxF2L(sp98, &gDisplayContext->matrixStack[gMatrixListPos]); + + gSPMatrix(gMasterGfxPos++, &gDisplayContext->matrixStack[gMatrixListPos++], + G_MTX_PUSH | G_MTX_MUL | G_MTX_MODELVIEW); + if (data->unk_20 > 4.0f) { + gDPSetPrimColor(gMasterGfxPos++, 0, 0, 255, 255, 255, 127); + } else { + gDPSetPrimColor(gMasterGfxPos++, 0, 0, 255, 255, 128, 127); + } + + gDPSetEnvColor(gMasterGfxPos++, 255, 255, 139, alpha); + + gSPDisplayList(gMasterGfxPos++, dlist); + gSPPopMatrix(gMasterGfxPos++, G_MTX_MODELVIEW); +} +#else INCLUDE_ASM(s32, "effects/blast", blast_appendGfx); +#endif diff --git a/src/effects/bombette_breaking.c b/src/effects/bombette_breaking.c index 123cf4a457..83953ce4bd 100644 --- a/src/effects/bombette_breaking.c +++ b/src/effects/bombette_breaking.c @@ -2,10 +2,10 @@ #include "model.h" #include "effects_internal.h" -void bombette_breaking_appendGfx(void* effect); void bombette_breaking_init(EffectInstance* effect); void bombette_breaking_update(EffectInstance* effect); void bombette_breaking_render(EffectInstance* effect); +void bombette_breaking_appendGfx(void* effect); extern Gfx D_090018C0[]; extern Gfx D_09001D00[]; @@ -21,24 +21,173 @@ void (*D_E0084E34)(u16, f32*, f32*, f32*, f32*, f32*, f32*) = get_model_center_a Model* (*D_E0084E38)(s32) = get_model_from_list_index; s32 (*D_E0084E3C)(s32) = get_model_list_index_from_tree_index; -void func_E0084000(s32 modelID, f32* centerX, f32* centerY, f32* centerZ, f32* sizeX, f32* sizeY, f32* sizeZ) { +void bombette_breaking_get_model_center_and_size(s32 modelID, + f32* centerX, f32* centerY, f32* centerZ, + f32* sizeX, f32* sizeY, f32* sizeZ) +{ D_E0084E34(modelID, centerX, centerY, centerZ, sizeX, sizeY, sizeZ); } -Model* func_E008403C(s32 listIndex) { +Model* bombette_breaking_get_model_from_list_index(s32 listIndex) { return D_E0084E38(listIndex); } -s32 func_E0084060(s32 listIndex) { +s32 bombette_breaking_get_model_list_index_from_tree_index(s32 listIndex) { return D_E0084E3C(listIndex); } -INCLUDE_ASM(s32, "effects/bombette_breaking", bombette_breaking_main); +EffectInstance* bombette_breaking_main(s32 type, s32 modelID, s32 treeIndex, f32 arg3, s32 arg4, s32 time) { + EffectBlueprint bp; + EffectBlueprint* bpPtr = &bp; + EffectInstance* effect; + s32 numParts; + BombetteBreakingFXData* data; + f32 centerX, centerY, centerZ; + f32 sizeX, sizeY, sizeZ; + s32 xParts, yParts, zParts; + s32 iX, iY, iZ; + f32 f20, f30, f40; + + bombette_breaking_get_model_center_and_size(modelID & 0xFFFF, ¢erX, ¢erY, ¢erZ, &sizeX, &sizeY, &sizeZ); + + xParts = (sizeX * 0.0625f) + 1.0f; + yParts = (sizeY * 0.0625f) + 1.0f; + zParts = (sizeZ * 0.0625f) + 1.0f; + + f20 = (s32)sizeX % 16; + f30 = (s32)sizeY % 16; + f40 = (s32)sizeZ % 16; + + bp.unk_00 = 0; + bp.init = bombette_breaking_init; + bp.update = bombette_breaking_update; + bp.renderWorld = bombette_breaking_render; + bp.unk_14 = 0; + bp.effectID = EFFECT_BOMBETTE_BREAKING; + + f20 *= 0.5; + f30 *= 0.5; + f40 *= 0.5; + + numParts = (xParts * yParts * zParts) + 1; + effect = shim_create_effect_instance(bpPtr); + effect->numParts = numParts; + effect->data.bombetteBreaking = data = shim_general_heap_malloc(numParts * sizeof(*data)); + ASSERT(data != NULL); + + data->unk_04 = -sizeY * 0.5; + data->timeLeft = time; + data->unk_48 = 0; + data->type = type; + data->unk_38 = arg3; + data->alpha = 255; + data->treeIndex = treeIndex; + data->unk_3C = 2.0f * arg3; + data->center.x = centerX; + data->center.y = centerY; + data->center.z = centerZ; + data->unk_40 = sizeY * 0.05; + if (data->unk_40 < 1.0f) { + data->unk_40 = 1.0f; + } + + data++; + for (iX = 0; iX < xParts; iX++) { + centerX = f20 - (sizeX * 0.5) + (iX * 16.0f); + for (iY = 0; iY < yParts; iY++) { + centerY = f30 - (sizeY * 0.5) + (iY * 16.0f); + for (iZ = 0; iZ < zParts; iZ++) { + centerZ = f30 - (sizeZ * 0.5) + (iZ * 16.0f); + + data->center.x = data->unk_14.x = centerX; + data->center.y = data->unk_14.y = centerY; + data->center.z = data->unk_14.z = centerZ; + + if (sizeX < sizeZ) { + if (xParts >= 2) { + data->unk_20.x = 2.0 * (centerX / (sizeX * 0.5)); + } else { + if (iZ & 1) { + data->unk_20.x = 2.0f; + } else { + data->unk_20.x = -2.0f; + } + } + data->unk_20.z = 0.0f; + } else { + data->unk_20.x = 0.0f; + if (zParts >= 2) { + data->unk_20.z = 2.0 * (centerZ / (sizeZ * 0.5)); + } else { + if (iX & 1) { + data->unk_20.z = 2.0f; + } else { + data->unk_20.z = -2.0f; + } + } + } + + data->unk_20.y = centerY * 0.2; + data->unk_2C.x = centerZ * 0.2 + (centerX < centerZ ? (centerZ < 0 ? -1.0 : (centerZ > 0 ? 1.0 : 0.0)) : 0.0); + data->unk_2C.y = centerY * 0.2; + data->unk_2C.z = centerX * 0.2 + (centerZ < centerX ? (centerX < 0 ? -1.0 : (centerX > 0 ? 1.0 : 0.0)) : 0.0); + + data->alpha = 255; + data++; + } + } + } + return effect; +} void bombette_breaking_init(EffectInstance* effect) { } -INCLUDE_ASM(s32, "effects/bombette_breaking", bombette_breaking_update); +void bombette_breaking_update(EffectInstance* effect) { + BombetteBreakingFXData* data = effect->data.bombetteBreaking; + f32 unk_04; + s32 i; + + data->unk_48++; + data->timeLeft--; + + if (data->timeLeft < 0) { + shim_remove_effect(effect); + return; + } + + unk_04 = data->unk_04; + + if (data->timeLeft < 25.0f) { + data->alpha = data->timeLeft * 10.0f; + } + data->unk_38 += (data->unk_3C - data->unk_38) * 0.1; + + data++; + for (i = 1; i < effect->numParts; i++, data++) { + data->unk_20.x *= 0.9; + data->unk_20.y *= 0.9; + data->unk_20.z *= 0.9; + data->center.x += data->unk_20.x; + data->center.y += data->unk_20.y; + data->center.z += data->unk_20.z; + if (data->center.y < unk_04 && data->unk_20.y < 0.0f) { + data->center.y = unk_04; + data->unk_20.y *= -0.7; + } + + data->unk_2C.x *= 0.95; + data->unk_2C.y -= 0.4; + data->unk_2C.z *= 0.95; + data->unk_14.x += data->unk_2C.x; + data->unk_14.y += data->unk_2C.y; + data->unk_14.z += data->unk_2C.z; + if (data->unk_14.y < unk_04 && data->unk_2C.y < 0.0f) { + data->unk_14.y = unk_04; + data->unk_2C.y *= -0.4; + } + } +} void bombette_breaking_render(EffectInstance* effect) { RenderTask renderTask; @@ -53,4 +202,53 @@ void bombette_breaking_render(EffectInstance* effect) { retTask->renderMode |= RENDER_TASK_FLAG_2; } -INCLUDE_ASM(s32, "effects/bombette_breaking", bombette_breaking_appendGfx); +void bombette_breaking_appendGfx(void* effect) { + Matrix4f sp20; + BombetteBreakingFXData* data = ((EffectInstance*)effect)->data.bombetteBreaking; + s32 timeLeft = data->timeLeft; + u16 type = data->type; + Gfx* sp60 = D_E0084E10[type]; + Gfx* sp64 = D_E0084E28[type]; + f32 unk_38 = data->unk_38; + f32 unk_40 = data->unk_40; + s32 mainAlpha = data->alpha; + s32 i; + + timeLeft *= 4; + + gDPPipeSync(gMasterGfxPos++); + gSPSegment(gMasterGfxPos++, 0x09, VIRTUAL_TO_PHYSICAL(((EffectInstance*)effect)->graphics->data)); + shim_guTranslateF(sp20, data->center.x, data->center.y, data->center.z); + shim_guMtxF2L(sp20, &gDisplayContext->matrixStack[gMatrixListPos]); + gSPMatrix(gMasterGfxPos++, &gDisplayContext->matrixStack[gMatrixListPos++], G_MTX_PUSH | G_MTX_MUL | G_MTX_MODELVIEW); + + shim_mdl_draw_hidden_panel_surface(&gMasterGfxPos, data->treeIndex); + + data++; + for (i = 1; i < ((EffectInstance*)effect)->numParts; i++, data++) { + shim_guPositionF(sp20, timeLeft + (130 * i), timeLeft - (40 * i), timeLeft + (80 * i), unk_40, + data->unk_14.x, data->unk_14.y, data->unk_14.z); + shim_guMtxF2L(sp20, &gDisplayContext->matrixStack[gMatrixListPos]); + gSPMatrix(gMasterGfxPos++, &gDisplayContext->matrixStack[gMatrixListPos++], + G_MTX_PUSH | G_MTX_MUL | G_MTX_MODELVIEW); + gSPDisplayList(gMasterGfxPos++, D_E0084E1C[type]); + gSPPopMatrix(gMasterGfxPos++, G_MTX_MODELVIEW); + } + + gSPDisplayList(gMasterGfxPos++, sp64); + + data = ((EffectInstance*)effect)->data.bombetteBreaking; + data++; + for (i = 1; i < ((EffectInstance*)effect)->numParts; i++, data++) { + gDPSetPrimColor(gMasterGfxPos++, 0, 0, 255, 255, 255, (data->alpha * mainAlpha) / 255); + shim_guPositionF(sp20, 0.0f, -gCameras[gCurrentCameraID].currentYaw, 0.0f, unk_38, + data->center.x, data->center.y, data->center.z); + shim_guMtxF2L(sp20, &gDisplayContext->matrixStack[gMatrixListPos]); + gSPMatrix(gMasterGfxPos++, &gDisplayContext->matrixStack[gMatrixListPos++], + G_MTX_PUSH | G_MTX_MUL | G_MTX_MODELVIEW); + gSPDisplayList(gMasterGfxPos++, sp60); + gSPPopMatrix(gMasterGfxPos++, G_MTX_MODELVIEW); + } + + gSPPopMatrix(gMasterGfxPos++, G_MTX_MODELVIEW); +} diff --git a/src/effects/breaking_junk.c b/src/effects/breaking_junk.c index c24c1d2216..7a29e305c6 100644 --- a/src/effects/breaking_junk.c +++ b/src/effects/breaking_junk.c @@ -1,14 +1,122 @@ #include "common.h" #include "effects_internal.h" +void breaking_junk_init(EffectInstance* effect); +void breaking_junk_update(EffectInstance* effect); +void breaking_junk_render(EffectInstance* effect); void breaking_junk_appendGfx(void* effect); -INCLUDE_ASM(s32, "effects/breaking_junk", breaking_junk_main); +extern Gfx D_09000400_403FF0[]; +extern Gfx D_090005A8_404198[]; +extern Gfx D_090005C8_4041B8[]; +extern Gfx D_090005E8_4041D8[]; +extern Gfx D_09000608_4041F8[]; -void breaking_junk_init(void) { +Gfx* D_E01187B0[] = { D_090005A8_404198, D_090005C8_4041B8, D_090005E8_4041D8, D_09000608_4041F8 }; + +Gfx* D_E01187C0[] = { D_09000400_403FF0 }; + +EffectInstance* breaking_junk_main(s32 arg0, f32 x, f32 y, f32 z, f32 scale, s32 time) { + EffectBlueprint bp; + EffectBlueprint* bpPtr = &bp; + EffectInstance* effect; + BreakingJunkFXData* data; + s32 numParts = 6; + u32 g; + s32 i; + + bp.unk_00 = 0; + bp.init = breaking_junk_init; + bp.update = breaking_junk_update; + bp.renderWorld = breaking_junk_render; + bp.unk_14 = 0; + bp.effectID = EFFECT_BREAKING_JUNK; + + effect = shim_create_effect_instance(bpPtr); + effect->numParts = numParts; + + data = effect->data.breakingJunk = shim_general_heap_malloc(numParts * sizeof(*data)); + + ASSERT(effect->data.breakingJunk != NULL); + + data->unk_00 = arg0; + data->lifeTime = 0; + if (time <= 0) { + data->timeLeft = 1000; + } else { + data->timeLeft = time; + } + data->primA = 255; + + for (i = 0; i < effect->numParts; i++, data++) { + data->pos.x = x; + data->pos.y = y; + data->pos.z = z; + data->vel.x = (shim_rand_int(10) - 5) * 0.5; + data->vel.y = (shim_rand_int(5) + 1) * 0.8; + data->vel.z = (shim_rand_int(10) - 5) * 0.5; + data->scale = scale; + data->primR = data->envR = shim_rand_int(255); + g = shim_rand_int(255 - data->envR); + data->primG = data->envG = g; + data->primB = data->envB = (255 - g) - data->envR; + data->primR += 168; + data->primG += 168; + data->primB += 168; + if (data->primR > 255) { + data->primR = 255; + } + if (data->primG > 255) { + data->primG = 255; + } + if (data->primB > 255) { + data->primB = 255; + } + data->envR = data->envR * 0.6; + data->envG = data->envG * 0.6; + data->envB = data->envB * 0.6; + data->rot = shim_rand_int(359); + } + return effect; } -INCLUDE_ASM(s32, "effects/breaking_junk", breaking_junk_update); +void breaking_junk_init(EffectInstance* effect) { +} + +void breaking_junk_update(EffectInstance* effect) { + BreakingJunkFXData* data = effect->data.breakingJunk; + s32 i; + + if (effect->flags & 0x10) { + effect->flags &= ~0x10; + data->timeLeft = 16; + } + if (data->timeLeft < 1000) { + data->timeLeft--; + } + + data->lifeTime++; + if (data->timeLeft < 0) { + shim_remove_effect(effect); + return; + } + + if (data->timeLeft < 8) { + data->primA = data->timeLeft * 32; + } + + for (i = 0; i < effect->numParts; i++, data++) { + data->vel.y -= 0.5; + data->pos.x += data->vel.x; + data->pos.y += data->vel.y; + data->pos.z += data->vel.z; + if (data->pos.y < 0.0f && data->vel.y < 0.0f) { + data->pos.y = 0.0f; + data->vel.y *= -0.7; + } + data->rot += (((i & 1) * 2) - 1) * 14; + } +} void breaking_junk_render(EffectInstance* effect) { RenderTask renderTask; @@ -23,4 +131,27 @@ void breaking_junk_render(EffectInstance* effect) { retTask->renderMode |= RENDER_TASK_FLAG_2; } -INCLUDE_ASM(s32, "effects/breaking_junk", breaking_junk_appendGfx); +void breaking_junk_appendGfx(void* effect) { + Matrix4f sp20, sp60; + BreakingJunkFXData* data = ((EffectInstance*)effect)->data.breakingJunk; + s32 alpha = data->primA; + s32 i; + + gDPPipeSync(gMasterGfxPos++); + gSPSegment(gMasterGfxPos++, 0x09, VIRTUAL_TO_PHYSICAL(((EffectInstance*)effect)->graphics->data)); + gSPDisplayList(gMasterGfxPos++, D_E01187C0[0]); + + for (i = 0; i < ((EffectInstance*)effect)->numParts; i++, data++) { + shim_guPositionF(sp20, 0.0f, -gCameras[gCurrentCameraID].currentYaw, 0.0f, data->scale * 0.5, data->pos.x, data->pos.y, data->pos.z); + shim_guRotateF(sp60, data->rot, 0.0f, 0.0f, 1.0f); + shim_guMtxCatF(sp60, sp20, sp20); + shim_guMtxF2L(sp20, &gDisplayContext->matrixStack[gMatrixListPos]); + gSPMatrix(gMasterGfxPos++, &gDisplayContext->matrixStack[gMatrixListPos++], G_MTX_PUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(gMasterGfxPos++, 0, 0, data->primR, data->primG, data->primB, alpha); + gDPSetEnvColor(gMasterGfxPos++, data->envR, data->envG, data->envB, data->envA); + gSPDisplayList(gMasterGfxPos++, D_E01187B0[(u32)i % ARRAY_COUNT(D_E01187B0)]); + gSPPopMatrix(gMasterGfxPos++, G_MTX_MODELVIEW); + } + + gDPPipeSync(gMasterGfxPos++); +} diff --git a/src/effects/cloud_puff.c b/src/effects/cloud_puff.c index d34afa842f..7f9e749559 100644 --- a/src/effects/cloud_puff.c +++ b/src/effects/cloud_puff.c @@ -45,7 +45,7 @@ void cloud_puff_main(f32 arg0, f32 arg1, f32 arg2, f32 arg3) { part->unk_24 = (shim_rand_int(10) * 0.03) + 1.0; part->unk_28 = (shim_rand_int(10) * 0.03) + 1.7; part->unk_2C = func_E0200000(60); - part->lifetime = 30; + part->timeLeft = 30; part->unk_34 = 0.5f; part->unk_38 = -0.02f; part->unk_3C = 0.00005f; @@ -66,8 +66,8 @@ void cloud_puff_update(EffectInstance* effect) { for (i = 0; i < effect->numParts; i++, part++) { if (part->alive) { - part->lifetime--; - if (part->lifetime <= 0) { + part->timeLeft--; + if (part->timeLeft <= 0) { part->alive = FALSE; } else { cond = TRUE; @@ -83,11 +83,11 @@ void cloud_puff_update(EffectInstance* effect) { part->unk_10 += part->unk_34; part->unk_28 *= 0.98; - if (part->lifetime < 10) { + if (part->timeLeft < 10) { part->unk_28 *= 0.9; } - if (part->lifetime < 15) { + if (part->timeLeft < 15) { part->alpha -= 16; } } diff --git a/src/effects/fire_breath.c b/src/effects/fire_breath.c index b7be42d602..bdbe9f6f91 100644 --- a/src/effects/fire_breath.c +++ b/src/effects/fire_breath.c @@ -59,8 +59,8 @@ EffectInstance* fire_breath_main( } data->unk_30 = data->scale; - data->maxLifetime = lifetime; - data->lifetime = lifetime; + data->lifeTime = lifetime; + data->timeLeft = lifetime; data->spawnTimer = 0; data->alpha = 255; data->unk_5C = 0.0f; @@ -93,30 +93,30 @@ void fire_breath_init(EffectInstance* effect) { void fire_breath_update(EffectInstance* effect) { FireBreathFXData* data = effect->data.fireBreath; - s32 maxLifetime; - s32 lifetime; + s32 lifeTime; + s32 timeLeft; s32 spawnTimer; - data->lifetime--; + data->timeLeft--; data->unk_5C = (data->spawnTimer * 4.0f) / 10.0f; data->spawnTimer++; - if (data->lifetime < 0) { + if (data->timeLeft < 0) { shim_remove_effect(effect); return; } - lifetime = data->lifetime; - maxLifetime = data->maxLifetime; + timeLeft = data->timeLeft; + lifeTime = data->lifeTime; spawnTimer = data->spawnTimer; - if (lifetime >= 6 && data->type == FIRE_BREATH_LARGE) { + if (timeLeft >= 6 && data->type == FIRE_BREATH_LARGE) { data->scale += (2.5 - data->scale) * 0.05; } - data->pos.x = data->initPos.x + (((data->endPos.x - data->initPos.x + data->unk_50.x) * spawnTimer) / maxLifetime); - data->pos.y = data->initPos.y + (((data->endPos.y - data->initPos.y + data->unk_50.y) * spawnTimer) / maxLifetime); - data->pos.z = data->initPos.z + (((data->endPos.z - data->initPos.z + data->unk_50.z) * spawnTimer) / maxLifetime); + data->pos.x = data->initPos.x + (((data->endPos.x - data->initPos.x + data->unk_50.x) * spawnTimer) / lifeTime); + data->pos.y = data->initPos.y + (((data->endPos.y - data->initPos.y + data->unk_50.y) * spawnTimer) / lifeTime); + data->pos.z = data->initPos.z + (((data->endPos.z - data->initPos.z + data->unk_50.z) * spawnTimer) / lifeTime); if (data->type == FIRE_BREATH_SMALL) { data->unk_60 += (f32) spawnTimer * 0.01; @@ -129,7 +129,7 @@ void fire_breath_update(EffectInstance* effect) { shim_load_effect(EFFECT_FIRE_BREATH); spawned = fire_breath_main( data->type, data->initPos.x, data->initPos.y, data->initPos.z, data->endPos.x, data->endPos.y, - data->endPos.z, data->numChildren - 1, data->spawnDelay, maxLifetime + data->endPos.z, data->numChildren - 1, data->spawnDelay, lifeTime ); spawned->data.fireBreath->primR = data->primR; @@ -143,18 +143,18 @@ void fire_breath_update(EffectInstance* effect) { spawned->data.fireBreath->scaleChangeFactor = data->scaleChangeFactor; } - if (lifetime < 10 && data->type == FIRE_BREATH_LARGE) { - data->alpha = lifetime * 25; + if (timeLeft < 10 && data->type == FIRE_BREATH_LARGE) { + data->alpha = timeLeft * 25; } if (data->type == FIRE_BREATH_SMALL) { data->scale += (0.3 - data->scale) * 0.008; - data->alpha = (lifetime * 224) / maxLifetime; + data->alpha = (timeLeft * 224) / lifeTime; } if (data->type == FIRE_BREATH_TINY) { data->scale += (data->unk_34 - data->scale) * data->scaleChangeFactor; - data->alpha = (lifetime * 224) / maxLifetime; + data->alpha = (timeLeft * 224) / lifeTime; } } diff --git a/src/effects/gfx/balloon.c b/src/effects/gfx/balloon.c new file mode 100644 index 0000000000..d55e77a32c --- /dev/null +++ b/src/effects/gfx/balloon.c @@ -0,0 +1,31 @@ +#include "common.h" + +#include "effects/gfx/D_09000000_394670.png.inc.c" +#include "effects/gfx/D_09000200_394870.png.inc.c" +#include "effects/gfx/D_09000000_394670.pal.inc.c" + +u8 D_09000420_394A90[] = { + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 +}; + +#include "effects/gfx/D_09000600_394C70.png.inc.c" +#include "effects/gfx/D_09000800_394E70.png.inc.c" +#include "effects/gfx/D_09000600_394C70.pal.inc.c" + +u8 D_09000A20_395090[] = { + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 +}; + +#include "effects/gfx/D_09000C00_395270.png.inc.c" +#include "effects/gfx/D_09000E00_395470.png.inc.c" +#include "effects/gfx/D_09000C00_395270.pal.inc.c" + +u8 D_09001020_395690[] = { + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 +}; + +#include "effects/gfx/D_09001200_395870.vtx.inc.c" +#include "effects/gfx/D_09001280_3958F0.gfx.inc.c" +#include "effects/gfx/D_09001358_3959C8.gfx.inc.c" +#include "effects/gfx/D_09001430_395AA0.gfx.inc.c" +#include "effects/gfx/D_09001508_395B78.gfx.inc.c" diff --git a/src/effects/gfx/breaking_junk.c b/src/effects/gfx/breaking_junk.c new file mode 100644 index 0000000000..0ae2840741 --- /dev/null +++ b/src/effects/gfx/breaking_junk.c @@ -0,0 +1,16 @@ +#include "common.h" + +#include "effects/gfx/D_09000000_403BF0.png.inc.c" +#include "effects/gfx/D_09000100_403CF0.png.inc.c" +#include "effects/gfx/D_09000200_403DF0.png.inc.c" +#include "effects/gfx/D_09000300_403EF0.png.inc.c" + +#include "effects/gfx/D_09000400_403FF0.gfx.inc.c" +#include "effects/gfx/D_090004A8_404098.vtx.inc.c" +#include "effects/gfx/D_090004E8_4040D8.vtx.inc.c" +#include "effects/gfx/D_09000528_404118.vtx.inc.c" +#include "effects/gfx/D_09000568_404158.vtx.inc.c" +#include "effects/gfx/D_090005A8_404198.gfx.inc.c" +#include "effects/gfx/D_090005C8_4041B8.gfx.inc.c" +#include "effects/gfx/D_090005E8_4041D8.gfx.inc.c" +#include "effects/gfx/D_09000608_4041F8.gfx.inc.c" diff --git a/src/effects/gfx/water_splash.c b/src/effects/gfx/water_splash.c new file mode 100644 index 0000000000..c9b05ed0ad --- /dev/null +++ b/src/effects/gfx/water_splash.c @@ -0,0 +1,12 @@ +#include "common.h" + +#include "effects/gfx/D_09000000_3BCA90.png.inc.c" +#include "effects/gfx/D_09000100_3BCB90.gfx.inc.c" + +#include "effects/gfx/D_090001A8_3BCC38.vtx.inc.c" +#include "effects/gfx/D_090001E8_3BCC78.vtx.inc.c" +#include "effects/gfx/D_09000228_3BCCB8.vtx.inc.c" + +#include "effects/gfx/D_09000268_3BCCF8.gfx.inc.c" +#include "effects/gfx/D_09000288_3BCD18.gfx.inc.c" +#include "effects/gfx/D_090002A8_3BCD38.gfx.inc.c" diff --git a/src/effects/snowflake.c b/src/effects/snowflake.c index 081004ec61..ded2fc9232 100644 --- a/src/effects/snowflake.c +++ b/src/effects/snowflake.c @@ -11,7 +11,7 @@ void snowflake_update(EffectInstance* effect); void snowflake_render(EffectInstance* effect); void snowflake_appendGfx(void* effect); -void snowflake_main(f32 arg0, f32 arg1, f32 arg2, s32 arg3, s32 arg4) { +void snowflake_main(f32 x, f32 y, f32 z, s32 arg3, s32 arg4) { EffectBlueprint bp; EffectInstance* effect; SnowflakeFXData* part; @@ -31,14 +31,14 @@ void snowflake_main(f32 arg0, f32 arg1, f32 arg2, s32 arg3, s32 arg4) { ASSERT(effect->data.snowflake != NULL); - part->xPos = arg0; - part->yPos = arg1; - part->zPos = arg2; + part->pos.x = x; + part->pos.y = y; + part->pos.z = z; part->unk_0C = 0; + part->unk_10 = -3.0f; part->unk_14 = 0; part->unk_18 = 0; part->unk_1C = 0; - part->unk_10 = -3.0f; part->unk_20 = 3.0f; if (D_E001C5E0 != 0) { phi_f4 = -10.0f; @@ -66,9 +66,9 @@ void snowflake_update(EffectInstance* effect) { return; } - data->xPos += data->unk_0C; - data->yPos += data->unk_10; - data->zPos += data->unk_14; + data->pos.x += data->unk_0C; + data->pos.y += data->unk_10; + data->pos.z += data->unk_14; data->unk_18 += data->unk_20; if (data->unk_18 < 10.0f) { data->unk_18 = 10.0f; @@ -83,28 +83,28 @@ void snowflake_update(EffectInstance* effect) { void snowflake_render(EffectInstance* effect) { PlayerStatus* playerStatus = &gPlayerStatus; - SnowflakeFXData* effect14 = effect->data.snowflake; + SnowflakeFXData* data = effect->data.snowflake; RenderTask renderTask; RenderTask* renderTaskPtr = &renderTask; RenderTask* retTask; - f32 effectPos = effect14->xPos; + f32 effectPos = data->pos.x; f32 playerPos = playerStatus->position.x; if (effectPos - playerPos > 200) { - effect14->xPos = effectPos - 400; + data->pos.x = effectPos - 400; } else { if (playerPos - effectPos > 200) { - effect14->xPos = effectPos + 400; + data->pos.x = effectPos + 400; } } - effectPos = effect14->zPos; + effectPos = data->pos.z; playerPos = playerStatus->position.z; if (effectPos - playerPos > 200) { - effect14->zPos = effectPos - 400; + data->pos.z = effectPos - 400; } else { if (playerPos - effectPos > 200) { - effect14->zPos = effectPos + 400; + data->pos.z = effectPos + 400; } } @@ -120,13 +120,13 @@ void snowflake_render(EffectInstance* effect) { void snowflake_appendGfx(void* effect) { Matrix4f sp18, sp58, sp98, spD8, sp118; EffectInstance* effectTemp = effect; - SnowflakeFXData* part = effectTemp->data.snowflake; + SnowflakeFXData* data = effectTemp->data.snowflake; gDPPipeSync(gMasterGfxPos++); gSPSegment(gMasterGfxPos++, 0x09, VIRTUAL_TO_PHYSICAL(effectTemp->graphics->data)); gSPDisplayList(gMasterGfxPos++, D_09000900_331800); - shim_guTranslateF(sp18, part->xPos, part->yPos, part->zPos); + shim_guTranslateF(sp18, data->pos.x, data->pos.y, data->pos.z); shim_guRotateF(spD8, -gCameras[gCurrentCameraID].currentYaw, 0.0f, 1.0f, 0.0f); shim_guMtxCatF(spD8, sp18, sp118); shim_guMtxF2L(sp118, &gDisplayContext->matrixStack[gMatrixListPos]); @@ -134,8 +134,8 @@ void snowflake_appendGfx(void* effect) { gSPMatrix(gMasterGfxPos++, &gDisplayContext->matrixStack[gMatrixListPos++], G_MTX_PUSH | G_MTX_MUL | G_MTX_MODELVIEW); gDPSetPrimColor(gMasterGfxPos++, 0, 0, 0, 0, 0, 255); - shim_guRotateF(sp58, part->unk_18, 1.0f, 0.0f, 0.0f); - shim_guRotateF(sp98, part->unk_1C, 0.0f, 1.0f, 0.0f); + shim_guRotateF(sp58, data->unk_18, 1.0f, 0.0f, 0.0f); + shim_guRotateF(sp98, data->unk_1C, 0.0f, 1.0f, 0.0f); shim_guMtxCatF(sp58, sp98, sp118); shim_guMtxF2L(sp118, &gDisplayContext->matrixStack[gMatrixListPos]); diff --git a/src/effects/water_splash.c b/src/effects/water_splash.c index 2b07b6abcf..bd3ced647c 100644 --- a/src/effects/water_splash.c +++ b/src/effects/water_splash.c @@ -1,6 +1,14 @@ #include "common.h" #include "effects_internal.h" +extern Gfx D_09000268_3BCCF8[]; +extern Gfx D_09000288_3BCD18[]; +extern Gfx D_090002A8_3BCD38[]; + +Gfx* D_E00BEAF0[] = { + D_09000268_3BCCF8, D_09000288_3BCD18, D_09000268_3BCCF8, D_090002A8_3BCD38 +}; + void water_splash_appendGfx(void* effect); INCLUDE_ASM(s32, "effects/water_splash", water_splash_main); diff --git a/src/sprite.c b/src/sprite.c index 7cbf11cc8a..b85fbaab59 100644 --- a/src/sprite.c +++ b/src/sprite.c @@ -92,15 +92,6 @@ PlayerSpriteSet spr_playerSpriteSets[] = { /* Peach */ { 6, 0x900, 0x00003C00 }, }; -void spr_appendGfx_component_flat( - Quad* vertices, - IMG_PTR raster, PAL_PTR palette, - s32 width, s32 height, - f32 arg5, - Matrix4f mtx, - s32 alpha -); - void spr_init_quad_cache(void) { s32 i; @@ -196,6 +187,16 @@ void spr_clear_quad_cache(void) { } } +void spr_appendGfx_component_flat( + Quad* vertices, + IMG_PTR raster, PAL_PTR palette, + s32 width, s32 height, + f32 arg5, + Matrix4f mtx, + s32 alpha +); + + INCLUDE_ASM(s32, "sprite", spr_appendGfx_component_flat); void spr_appendGfx_component( diff --git a/src/sprite.h b/src/sprite.h index 94b98541f1..7f12ea5eaa 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -32,7 +32,7 @@ typedef struct SpriteAnimComponent { // TODO: consider moving to 101b90_len_8f0 (sprite_cache) typedef struct SpriteRasterCacheEntry { - /* 0x00 */ void* image; + /* 0x00 */ IMG_PTR image; /* 0x04 */ u8 width; /* 0x05 */ u8 height; /* 0x06 */ s8 palette; @@ -71,7 +71,7 @@ typedef struct PlayerSpriteCacheEntry { /* 0x00 */ s32 lazyDeleteTime; /* 0x04 */ s32 rasterIndex; /* 0x08 */ s32 spriteIndex; - /* 0x0C */ IMG_PTR* raster; + /* 0x0C */ IMG_PTR raster; } PlayerSpriteCacheEntry; // size = 0x10 /// Sprite data header. diff --git a/tools/migrate_effect_rodata.py b/tools/migrate_effect_rodata.py new file mode 100755 index 0000000000..08480e3cf2 --- /dev/null +++ b/tools/migrate_effect_rodata.py @@ -0,0 +1,149 @@ +#!/usr/bin/python3 + +import os +from pathlib import Path + +script_dir = os.path.dirname(os.path.realpath(__file__)) +root_dir = script_dir + "/../" +asm_dir = root_dir + "ver/current/asm/" +asm_effects_dir = asm_dir + "nonmatchings/effects/" +asm_data_dir = asm_dir + "data/effects/" + +data_to_thing = { + "337F10": "sparkles", + "339F10": "shape_spell", + "33BB70": "gather_energy_pink", + "33D5D0": "drop_leaves", + "33EFE0": "dust", + "3407C0": "shattering_stones", + "342120": "smoke_ring", + "342FD0": "damage_stars", + "343F30": "explosion", + "345190": "lens_flare", + "345B10": "got_item_outline", + "34E710": "spiky_white_aura", + "34F480": "smoke_impact", + "352CB0": "purple_ring", + "354F20": "stars_burst", + "355D10": "stars_shimmer", + "3564E0": "rising_bubble", + "357380": "ring_blast", + "359320": "shockwave", + "35A580": "music_note", + "35BFB0": "smoke_burst", + "35C530": "sweat", + "35E8A0": "windy_leaves", + "35F0A0": "falling_leaves", + "360A10": "stars_spread", + "361640": "steam_burst", + "362C30": "stars_orbiting", + "365970": "green_impact", + "366C80": "radial_shimmer", + "36AE80": "ending_decals", + "36DE10": "light_rays", + "36ED30": "lightning", + "374D80": "shimmer_burst", + "375500": "energy_shockwave", + "376FC0": "shimmer_wave", + "37ACF0": "bulb_glow", + "37D140": "effect_3D", + "38A2F0": "firework", + "38BAB0": "confetti", + "38D040": "snowfall", + "38E8F0": "effect_46", + "38F6F0": "gather_magic", + "393080": "flashing_box_shockwave", + "3960C0": "floating_rock", + "397010": "chomp_drop", + "3BD770": "snowman_doll", + "3C1B60": "fright_jar", + "3CB7C0": "stop_watch", + "3CD670": "effect_63", + "3D11B0": "effect_65", + "3D2460": "tubba_heart_attack", + "3D3910": "whirlwind", + "3D4930": "red_impact", + "3D4E70": "floating_cloud_puff", + "3D5E60": "energy_in_out", + "3D7740": "shiny_flare", + "3D80B0": "huff_puff_breath", + "3D8F30": "cold_breath", + "3DBEA0": "embers", + "3DCD00": "hieroglyphs", + "3DED90": "misc_particles", + "3E11B0": "static_status", + "3E1CC0": "moving_cloud", + "3E5060": "firework_rocket", + "3E5ED0": "peach_star_beam", + "3EBC30": "chapter_change", + "3F8CA0": "ice_shard", + "3FA480": "spirit_card", + "3FF180": "lil_oink", + "4032A0": "something_rotating", + "403BB0": "breaking_junk", + "404E40": "partner_buff", + "407040": "quizmo_assistant", + "40A180": "ice_pillar", + "40BB70": "sun", + "40D130": "star_spirits_energy", + "412FD0": "pink_sparkles", + "413F20": "star_outline", +} + +def handle_symbol(effect, symbol): + for root, dirs, files in os.walk(asm_effects_dir + effect + "/"): + for f_name in files: + if f_name.endswith(".s"): + f_path = os.path.join(root, f_name) + + with open(f_path) as f: + asm_lines = f.readlines() + + has_rodata_section = False + for line in asm_lines: + if ".section .rodata" in line: + has_rodata_section = True + continue + if symbol[1] in line: + if not has_rodata_section: + asm_lines.insert(3, ".section .rodata\n") + asm_lines.insert(4, "\n") + asm_lines.insert(5, ".section .text\n") + asm_lines.insert(6, "\n") + asm_lines.insert(5, f"dlabel {symbol[1]}\n") + asm_lines.insert(6, f"{symbol[2]}\n") + asm_lines.insert(7, "\n") + + with open(f_path, "w", newline="\n") as f: + f.write("".join(asm_lines)) + + return True + return False + + +def handle_file(f_path): + with open(f_path) as f: + rodata_lines = f.readlines()[4:] + + effect = f_path.split("/")[-1].split(".")[0] + + symbols = [] + for i in range(0, len(rodata_lines), 3): + l1 = rodata_lines[i].strip() + l2 = rodata_lines[i + 1].strip() + symbols.append((i + 4, l1.split()[1], l2)) + + for symbol in reversed(symbols): + if symbol[2].startswith(".word") and not symbol[1].startswith("jtbl_"): + print("skipping" + str(symbol)) + continue + migrated = handle_symbol(data_to_thing[effect], symbol) + +# Walk through asm files and rename stuff +print("Walking through asm files") +for root, dirs, files in os.walk(asm_data_dir): + for f_name in files: + if f_name.endswith(".data.s"): + f_path = os.path.join(root, f_name) + + handle_file(f_path) diff --git a/tools/splat/.gitrepo b/tools/splat/.gitrepo index a3d7f424b2..763bc0fe37 100644 --- a/tools/splat/.gitrepo +++ b/tools/splat/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/ethteck/splat.git branch = master - commit = fd9cbc3a16ce6e7a4ba81ca36c1ee35472d9c0c2 - parent = 70aeffbdc06b9b84e4e848a412afc5c6e9cde4bd + commit = b681843a788a48824ca60d5063a8f6494e444ddc + parent = de8a76e84bb952636a1caee8408417bcedf4a326 method = merge cmdver = 0.4.3 diff --git a/tools/splat/CHANGELOG.md b/tools/splat/CHANGELOG.md index e561dce15b..53e084737d 100644 --- a/tools/splat/CHANGELOG.md +++ b/tools/splat/CHANGELOG.md @@ -1,5 +1,8 @@ # splat Release Notes +### 0.9.2 +* Added "palette" argument to ci4/ci8 segments so that segments' palettes can be manually specified + ### 0.9.1 * Fixed a bug in which local labels and jump table labels could replace raw words in data blobs during data disassembly @@ -22,11 +25,11 @@ We plan to roll this out in phases. Currently, it only handles actual code disas ### Global options changes -The new `symbol_name_format` option allows specification of how symbols will be named. This can be set as a global option and also changed per-segment. `symbol_norom_name_format` is used when the symbol does not have a rom address (BSS). +The new `symbol_name_format` option allows specification of how symbols will be named. This can be set as a global option and also changed per-segment. `symbol_name_format_no_rom` is used when the symbol does not have a rom address (BSS). The following substitutions are allowed: -`$ROM` - the rom address of the symbol, hex-formatted and padded to 6 characters (ABCF10, 000030, 123456) (note: only for `symbol_name_format`, usage in `symbol_norom_name_format` will cause an error) +`$ROM` - the rom address of the symbol, hex-formatted and padded to 6 characters (ABCF10, 000030, 123456) (note: only for `symbol_name_format`, usage in `symbol_name_format_no_rom` will cause an error) `$VRAM` - the vram address of the symbol, hex-formatted and padded to 8 characters (00030010, 00020015, ABCDEF10) @@ -34,14 +37,14 @@ The new `symbol_name_format` option allows specification of how symbols will be The default values for these options are as follows -`symbol_name_format` : `$VRAM_$ROM` +`symbol_name_format` : `$VRAM` -`symbol_noram_name_format` : `$VRAM_$SEG` +`symbol_name_format_no_rom` : `$VRAM_$SEG` The appropriate prefix string will still automatically be applied depending on the type of the symbol: `D_` for data, `jtbl_` for jump tables, and `func_` for functions. This functionality may be customizable in the future. ---- -The `auto_all_section` option now should be a list of section names (`[".data", ".rodata", ".bss"]` by default) indicating the sections that should be linked from .o files built from source files (.c or asm/hasm .s files), when no subsegment explicitly indicates linking this type of section. +The `auto_all_sections` option now should be a list of section names (`[".data", ".rodata", ".bss"]` by default) indicating the sections that should be linked from .o files built from source files (.c or asm/hasm .s files), when no subsegment explicitly indicates linking this type of section. For example, if any subsegment of a code segment is of segment type `data` or `.data`, the `.data` section from all `c`/`asm`/`hasm` subsegments will not be linked unless explicitly indicated with a relevant `.data` subsegment. diff --git a/tools/splat/segtypes/n64/ci8.py b/tools/splat/segtypes/n64/ci8.py index 1ad5bd04a8..6aa15bdb3a 100644 --- a/tools/splat/segtypes/n64/ci8.py +++ b/tools/splat/segtypes/n64/ci8.py @@ -43,7 +43,15 @@ class N64SegCi8(N64SegRgba16): ) self.palette: "Optional[Palette]" = None - self.palette_name = self.name + + palette_name = self.name + if isinstance(yaml, dict): + if "palette" in yaml: + palette_name = yaml["palette"] + elif len(args) > 2: + palette_name = args[2] + + self.palette_name = palette_name def split(self, rom_bytes): path = options.get_asset_path() / self.dir / (self.name + ".png") diff --git a/tools/splat/segtypes/n64/ia16.py b/tools/splat/segtypes/n64/ia16.py index 8fd1e4c833..f4cbaf6fe6 100644 --- a/tools/splat/segtypes/n64/ia16.py +++ b/tools/splat/segtypes/n64/ia16.py @@ -3,16 +3,17 @@ from util import iter class N64SegIa16(N64SegIa4): - @staticmethod - def parse_image(data, width, height, flip_h=False, flip_v=False): - img = bytearray() + def split(self, rom_bytes): + path = self.out_path() + path.parent.mkdir(parents=True, exist_ok=True) - for x, y, i in iter.iter_image_indexes(width, height, 2, 1, flip_h, flip_v): - i1 = data[i] - a1 = data[i + 1] - img += bytes((i1, a1)) + data = rom_bytes[self.rom_start : self.rom_end] - return img + w = self.__class__.get_writer(self.width, self.height) + with open(path, "wb") as f: + w.write_array(f, data) + + self.log(f"Wrote {self.name} to {path}") def max_length(self): return self.width * self.height * 2 diff --git a/tools/splat/split.py b/tools/splat/split.py index 7a6178da23..fbe8eb852b 100755 --- a/tools/splat/split.py +++ b/tools/splat/split.py @@ -20,7 +20,7 @@ from util.symbols import Symbol from intervaltree import Interval, IntervalTree -VERSION = "0.9.0" +VERSION = "0.9.2" parser = argparse.ArgumentParser( description="Split a rom given a rom, a config, and output directory" diff --git a/tools/splat/util/palettes.py b/tools/splat/util/palettes.py index 6e8ca910e2..7ab5e81cdb 100644 --- a/tools/splat/util/palettes.py +++ b/tools/splat/util/palettes.py @@ -1,21 +1,19 @@ -from typing import Dict +from typing import Dict, Union +from segtypes.n64.ci4 import N64SegCi4, N64SegCi8 from segtypes.n64.palette import N64SegPalette as Palette -from segtypes.n64.ci8 import N64SegCi8 as Raster from segtypes.common.group import CommonSegGroup # Resolve Raster#palette and Palette#raster links def initialize(all_segments): - global palettes_remaining - def process(segments): - raster_map: Dict[str, Raster] = {} + raster_map: Dict[str, Union[N64SegCi4, N64SegCi8]] = {} palette_map: Dict[str, Palette] = {} for segment in segments: if isinstance(segment, Palette): palette_map[segment.name] = segment - if isinstance(segment, Raster): + if isinstance(segment, N64SegCi4) or isinstance(segment, N64SegCi8): raster_map[segment.name] = segment if isinstance(segment, CommonSegGroup): diff --git a/ver/us/asm/data/effects/330440.data.s b/ver/us/asm/data/effects/330440.data.s deleted file mode 100644 index 9595b41fc4..0000000000 --- a/ver/us/asm/data/effects/330440.data.s +++ /dev/null @@ -1,12 +0,0 @@ -.include "macro.inc" - -.section .data - -dlabel D_E001A610 -.word 0x00000000, 0x00000000, 0x00000000, 0x00000000 - -dlabel D_E001A620 -.double 0.001 - -dlabel D_E001A628 -.double 0.0007 diff --git a/ver/us/asm/data/effects/337F10.data.s b/ver/us/asm/data/effects/337F10.data.s index af046952bc..0fccc685f9 100644 --- a/ver/us/asm/data/effects/337F10.data.s +++ b/ver/us/asm/data/effects/337F10.data.s @@ -13,27 +13,3 @@ dlabel D_E0022D14 dlabel D_E0022D1C .ascii "