1
0
mirror of https://github.com/zeldaret/oot.git synced 2024-09-21 21:04:43 +00:00

improve matches (#1542)

This commit is contained in:
engineer124 2023-09-21 00:41:03 +10:00 committed by GitHub
parent 107c0288cc
commit a8d670fe5c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 146 additions and 140 deletions

View File

@ -277,47 +277,52 @@ void DemoKekkai_DrawTrialBarrier(Actor* thisx, PlayState* play2) {
Vtx* energyVtx = SEGMENTED_TO_VIRTUAL(gTrialBarrierEnergyVtx); Vtx* energyVtx = SEGMENTED_TO_VIRTUAL(gTrialBarrierEnergyVtx);
s32 i; s32 i;
if (this->orbScale != 0.0f) { if (this->orbScale == 0.0f) {
if (1) {} return;
alphas[2] = (s32)(this->energyAlpha * 202.0f);
alphas[1] = (s32)(this->energyAlpha * 126.0f);
alphas[0] = 0;
for (i = 0; i < 102; i++) {
energyVtx[i].v.cn[3] = alphas[alphaIndex[i]];
}
colorIndex = (this->actor.params - 1) * 6;
OPEN_DISPS(play->state.gfxCtx, "../z_demo_kekkai.c", 632);
Gfx_SetupDL_25Xlu(play->state.gfxCtx);
Matrix_Push();
Matrix_Translate(0.0f, 1200.0f, 0.0f, MTXMODE_APPLY);
Matrix_Scale(this->orbScale, this->orbScale, this->orbScale, MTXMODE_APPLY);
Matrix_Translate(0.0f, -1200.0f, 0.0f, MTXMODE_APPLY);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, "../z_demo_kekkai.c", 639),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPSegment(POLY_XLU_DISP++, 0x09,
Gfx_TwoTexScroll(play->state.gfxCtx, G_TX_RENDERTILE, frames * 5, frames * -10, 0x20, 0x20, 1,
frames * 5, frames * -10, 0x20, 0x20));
gSPDisplayList(POLY_XLU_DISP++, gTrialBarrierOrbDL);
Matrix_Pop();
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, "../z_demo_kekkai.c", 656),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gDPPipeSync(POLY_XLU_DISP++);
gDPSetPrimColor(POLY_XLU_DISP++, 0x00, 0x80, 50, 0, 100, 255);
gSPSegment(
POLY_XLU_DISP++, 0x0A,
Gfx_TwoTexScroll(play->state.gfxCtx, G_TX_RENDERTILE, 0, 0, 0x20, 0x20, 1, frames, frames, 0x20, 0x20));
gSPDisplayList(POLY_XLU_DISP++, gTrialBarrierFloorDL);
gDPPipeSync(POLY_XLU_DISP++);
gDPSetPrimColor(POLY_XLU_DISP++, 0x00, 0x80, sEnergyColors[colorIndex + 0], sEnergyColors[colorIndex + 1],
sEnergyColors[colorIndex + 2], 255);
gDPSetEnvColor(POLY_XLU_DISP++, sEnergyColors[colorIndex + 3], sEnergyColors[colorIndex + 4],
sEnergyColors[colorIndex + 5], 128);
gSPSegment(POLY_XLU_DISP++, 0x08,
Gfx_TwoTexScroll(play->state.gfxCtx, G_TX_RENDERTILE, frames * 5, frames * -10, 0x20, 0x20, 1,
frames * 5, frames * -10, 0x20, 0x40));
gSPDisplayList(POLY_XLU_DISP++, gTrialBarrierEnergyDL);
CLOSE_DISPS(play->state.gfxCtx, "../z_demo_kekkai.c", 696);
} }
alphas[2] = (s32)(this->energyAlpha * 202.0f);
alphas[1] = (s32)(this->energyAlpha * 126.0f);
alphas[0] = 0;
for (i = 0; i < 102; i++) {
energyVtx[i].v.cn[3] = alphas[alphaIndex[i]];
}
colorIndex = (this->actor.params - 1) * 6;
OPEN_DISPS(play->state.gfxCtx, "../z_demo_kekkai.c", 632);
Gfx_SetupDL_25Xlu(play->state.gfxCtx);
Matrix_Push();
Matrix_Translate(0.0f, 1200.0f, 0.0f, MTXMODE_APPLY);
Matrix_Scale(this->orbScale, this->orbScale, this->orbScale, MTXMODE_APPLY);
Matrix_Translate(0.0f, -1200.0f, 0.0f, MTXMODE_APPLY);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, "../z_demo_kekkai.c", 639),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPSegment(POLY_XLU_DISP++, 0x09,
Gfx_TwoTexScroll(play->state.gfxCtx, G_TX_RENDERTILE, frames * 5, frames * -10, 0x20, 0x20, 1,
frames * 5, frames * -10, 0x20, 0x20));
gSPDisplayList(POLY_XLU_DISP++, gTrialBarrierOrbDL);
Matrix_Pop();
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, "../z_demo_kekkai.c", 656),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gDPPipeSync(POLY_XLU_DISP++);
gDPSetPrimColor(POLY_XLU_DISP++, 0x00, 0x80, 50, 0, 100, 255);
gSPSegment(POLY_XLU_DISP++, 0x0A,
Gfx_TwoTexScroll(play->state.gfxCtx, G_TX_RENDERTILE, 0, 0, 0x20, 0x20, 1, frames, frames, 0x20, 0x20));
gSPDisplayList(POLY_XLU_DISP++, gTrialBarrierFloorDL);
gDPPipeSync(POLY_XLU_DISP++);
gDPSetPrimColor(POLY_XLU_DISP++, 0x00, 0x80, sEnergyColors[colorIndex + 0], sEnergyColors[colorIndex + 1],
sEnergyColors[colorIndex + 2], 255);
gDPSetEnvColor(POLY_XLU_DISP++, sEnergyColors[colorIndex + 3], sEnergyColors[colorIndex + 4],
sEnergyColors[colorIndex + 5], 128);
gSPSegment(POLY_XLU_DISP++, 0x08,
Gfx_TwoTexScroll(play->state.gfxCtx, G_TX_RENDERTILE, frames * 5, frames * -10, 0x20, 0x20, 1,
frames * 5, frames * -10, 0x20, 0x40));
gSPDisplayList(POLY_XLU_DISP++, gTrialBarrierEnergyDL);
CLOSE_DISPS(play->state.gfxCtx, "../z_demo_kekkai.c", 696);
} }
void DemoKekkai_DrawTowerBarrier(Actor* thisx, PlayState* play) { void DemoKekkai_DrawTowerBarrier(Actor* thisx, PlayState* play) {

View File

@ -281,26 +281,23 @@ void EffDust_DrawFunc_8099E4F4(Actor* thisx, PlayState* play2) {
gSPSegment(POLY_XLU_DISP++, 0x08, sEmptyDL); gSPSegment(POLY_XLU_DISP++, 0x08, sEmptyDL);
for (i = 0; i < 64; i++) { for (i = 0; i < 64; i++, initialPositions++, distanceTraveled++) {
if (*distanceTraveled < 1.0f) { if (!(*distanceTraveled < 1.0f)) {
aux = 1.0f - (*distanceTraveled * *distanceTraveled); continue;
Matrix_Translate(this->actor.world.pos.x + (initialPositions->x * ((this->dx * aux) + (1.0f - this->dx))),
this->actor.world.pos.y + (initialPositions->y * ((this->dy * aux) + (1.0f - this->dy))),
this->actor.world.pos.z + (initialPositions->z * ((this->dz * aux) + (1.0f - this->dz))),
MTXMODE_NEW);
Matrix_Scale(this->scalingFactor, this->scalingFactor, this->scalingFactor, MTXMODE_APPLY);
Matrix_Mult(&play->billboardMtxF, MTXMODE_APPLY);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx, "../z_eff_dust.c", 449),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(gEffSparklesDL));
} }
initialPositions++; aux = 1.0f - SQ(*distanceTraveled);
distanceTraveled++; Matrix_Translate(this->actor.world.pos.x + (initialPositions->x * ((this->dx * aux) + (1.0f - this->dx))),
// Needed for matching. this->actor.world.pos.y + (initialPositions->y * ((this->dy * aux) + (1.0f - this->dy))),
if (0) {} this->actor.world.pos.z + (initialPositions->z * ((this->dz * aux) + (1.0f - this->dz))),
MTXMODE_NEW);
Matrix_Scale(this->scalingFactor, this->scalingFactor, this->scalingFactor, MTXMODE_APPLY);
Matrix_Mult(&play->billboardMtxF, MTXMODE_APPLY);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx, "../z_eff_dust.c", 449),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(gEffSparklesDL));
} }
CLOSE_DISPS(gfxCtx, "../z_eff_dust.c", 458); CLOSE_DISPS(gfxCtx, "../z_eff_dust.c", 458);
@ -333,33 +330,29 @@ void EffDust_DrawFunc_8099E784(Actor* thisx, PlayState* play2) {
gSPSegment(POLY_XLU_DISP++, 0x08, sEmptyDL); gSPSegment(POLY_XLU_DISP++, 0x08, sEmptyDL);
for (i = 0; i < 64; i++) { for (i = 0; i < 64; i++, initialPositions++, distanceTraveled++) {
if (*distanceTraveled < 1.0f) { if (!(*distanceTraveled < 1.0f)) {
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, *distanceTraveled * 255); continue;
// Needed to match.
if (!this) {}
aux = 1.0f - (*distanceTraveled * *distanceTraveled);
Matrix_Mult(&player->mf_9E0, MTXMODE_NEW);
Matrix_Translate(initialPositions->x * ((this->dx * aux) + (1.0f - this->dx)),
initialPositions->y * (1.0f - *distanceTraveled) + 320.0f,
initialPositions->z * (1.0f - *distanceTraveled) + -20.0f, MTXMODE_APPLY);
Matrix_Scale(*distanceTraveled * this->scalingFactor, *distanceTraveled * this->scalingFactor,
*distanceTraveled * this->scalingFactor, MTXMODE_APPLY);
Matrix_ReplaceRotation(&play->billboardMtxF);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx, "../z_eff_dust.c", 506),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(gEffSparklesDL));
} }
initialPositions++; gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, *distanceTraveled * 255);
distanceTraveled++;
aux = 1.0f - SQ(*distanceTraveled);
Matrix_Mult(&player->mf_9E0, MTXMODE_NEW);
Matrix_Translate(initialPositions->x * ((this->dx * aux) + (1.0f - this->dx)),
initialPositions->y * (1.0f - *distanceTraveled) + 320.0f,
initialPositions->z * (1.0f - *distanceTraveled) + -20.0f, MTXMODE_APPLY);
Matrix_Scale(*distanceTraveled * this->scalingFactor, *distanceTraveled * this->scalingFactor,
*distanceTraveled * this->scalingFactor, MTXMODE_APPLY);
Matrix_ReplaceRotation(&play->billboardMtxF);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx, "../z_eff_dust.c", 506),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(gEffSparklesDL));
} }
CLOSE_DISPS(gfxCtx, "../z_eff_dust.c", 515); CLOSE_DISPS(gfxCtx, "../z_eff_dust.c", 515);

View File

@ -881,29 +881,34 @@ void EnFd_DrawEffectsFlames(EnFd* this, PlayState* play) {
EnFdEffect* eff = this->effects; EnFdEffect* eff = this->effects;
OPEN_DISPS(play->state.gfxCtx, "../z_en_fd.c", 1969); OPEN_DISPS(play->state.gfxCtx, "../z_en_fd.c", 1969);
materialFlag = false; materialFlag = false;
if (1) {}
Gfx_SetupDL_25Xlu(play->state.gfxCtx); Gfx_SetupDL_25Xlu(play->state.gfxCtx);
for (i = 0; i < EN_FD_EFFECT_COUNT; i++, eff++) { for (i = 0; i < EN_FD_EFFECT_COUNT; i++, eff++) {
if (eff->type == FD_EFFECT_FLAME) { if (eff->type != FD_EFFECT_FLAME) {
if (!materialFlag) { continue;
POLY_XLU_DISP = Gfx_SetupDL(POLY_XLU_DISP, SETUPDL_0);
gSPDisplayList(POLY_XLU_DISP++, gFlareDancerDL_7928);
gDPSetEnvColor(POLY_XLU_DISP++, 255, 10, 0, (u8)((this->fadeAlpha / 255.0f) * 255));
materialFlag = true;
}
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 0, (u8)((this->fadeAlpha / 255.0f) * 255));
gDPPipeSync(POLY_XLU_DISP++);
Matrix_Translate(eff->pos.x, eff->pos.y, eff->pos.z, MTXMODE_NEW);
Matrix_ReplaceRotation(&play->billboardMtxF);
Matrix_Scale(eff->scale, eff->scale, 1.0f, MTXMODE_APPLY);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, "../z_en_fd.c", 2006),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
idx = eff->timer * (8.0f / eff->initialTimer);
gSPSegment(POLY_XLU_DISP++, 0x8, SEGMENTED_TO_VIRTUAL(dustTextures[idx]));
gSPDisplayList(POLY_XLU_DISP++, gFlareDancerSquareParticleDL);
} }
if (!materialFlag) {
POLY_XLU_DISP = Gfx_SetupDL(POLY_XLU_DISP, SETUPDL_0);
gSPDisplayList(POLY_XLU_DISP++, gFlareDancerDL_7928);
gDPSetEnvColor(POLY_XLU_DISP++, 255, 10, 0, (u8)((this->fadeAlpha / 255.0f) * 255));
materialFlag = true;
}
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 0, (u8)((this->fadeAlpha / 255.0f) * 255));
gDPPipeSync(POLY_XLU_DISP++);
Matrix_Translate(eff->pos.x, eff->pos.y, eff->pos.z, MTXMODE_NEW);
Matrix_ReplaceRotation(&play->billboardMtxF);
Matrix_Scale(eff->scale, eff->scale, 1.0f, MTXMODE_APPLY);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, "../z_en_fd.c", 2006),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
idx = eff->timer * (8.0f / eff->initialTimer);
gSPSegment(POLY_XLU_DISP++, 0x8, SEGMENTED_TO_VIRTUAL(dustTextures[idx]));
gSPDisplayList(POLY_XLU_DISP++, gFlareDancerSquareParticleDL);
} }
CLOSE_DISPS(play->state.gfxCtx, "../z_en_fd.c", 2020); CLOSE_DISPS(play->state.gfxCtx, "../z_en_fd.c", 2020);
} }
@ -918,23 +923,25 @@ void EnFd_DrawEffectsDots(EnFd* this, PlayState* play) {
Gfx_SetupDL_25Xlu(play->state.gfxCtx); Gfx_SetupDL_25Xlu(play->state.gfxCtx);
for (i = 0; i < EN_FD_EFFECT_COUNT; i++, eff++) { for (i = 0; i < EN_FD_EFFECT_COUNT; i++, eff++) {
if (eff->type == FD_EFFECT_DOT) { if (eff->type != FD_EFFECT_DOT) {
if (!materialFlag) { continue;
Gfx_SetupDL_25Xlu(play->state.gfxCtx);
gSPDisplayList(POLY_XLU_DISP++, gFlareDancerDL_79F8);
materialFlag = true;
}
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, eff->color.r, eff->color.g, eff->color.b,
(u8)(eff->color.a * (this->fadeAlpha / 255.0f)));
gDPPipeSync(POLY_XLU_DISP++);
if (1) {}
Matrix_Translate(eff->pos.x, eff->pos.y, eff->pos.z, MTXMODE_NEW);
Matrix_ReplaceRotation(&play->billboardMtxF);
Matrix_Scale(eff->scale, eff->scale, 1.0f, MTXMODE_APPLY);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, "../z_en_fd.c", 2064),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gFlareDancerTriangleParticleDL);
} }
if (!materialFlag) {
Gfx_SetupDL_25Xlu(play->state.gfxCtx);
gSPDisplayList(POLY_XLU_DISP++, gFlareDancerDL_79F8);
materialFlag = true;
}
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, eff->color.r, eff->color.g, eff->color.b,
(u8)(eff->color.a * (this->fadeAlpha / 255.0f)));
gDPPipeSync(POLY_XLU_DISP++);
Matrix_Translate(eff->pos.x, eff->pos.y, eff->pos.z, MTXMODE_NEW);
Matrix_ReplaceRotation(&play->billboardMtxF);
Matrix_Scale(eff->scale, eff->scale, 1.0f, MTXMODE_APPLY);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, "../z_en_fd.c", 2064),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gFlareDancerTriangleParticleDL);
} }
CLOSE_DISPS(play->state.gfxCtx, "../z_en_fd.c", 2071); CLOSE_DISPS(play->state.gfxCtx, "../z_en_fd.c", 2071);

View File

@ -461,29 +461,30 @@ void EnFw_DrawEffects(EnFw* this, PlayState* play) {
materialFlag = false; materialFlag = false;
Gfx_SetupDL_25Xlu(play->state.gfxCtx); Gfx_SetupDL_25Xlu(play->state.gfxCtx);
if (1) {}
for (i = 0; i < EN_FW_EFFECT_COUNT; i++, eff++) { for (i = 0; i < EN_FW_EFFECT_COUNT; i++, eff++) {
if (eff->type != 0) { if (eff->type == 0) {
if (!materialFlag) { continue;
POLY_XLU_DISP = Gfx_SetupDL(POLY_XLU_DISP, SETUPDL_0);
gSPDisplayList(POLY_XLU_DISP++, gFlareDancerDL_7928);
gDPSetEnvColor(POLY_XLU_DISP++, 100, 60, 20, 0);
materialFlag = true;
}
alpha = eff->timer * (255.0f / eff->initialTimer);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 170, 130, 90, alpha);
gDPPipeSync(POLY_XLU_DISP++);
Matrix_Translate(eff->pos.x, eff->pos.y, eff->pos.z, MTXMODE_NEW);
Matrix_ReplaceRotation(&play->billboardMtxF);
Matrix_Scale(eff->scale, eff->scale, 1.0f, MTXMODE_APPLY);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, "../z_en_fw.c", 1229),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
idx = eff->timer * (8.0f / eff->initialTimer);
gSPSegment(POLY_XLU_DISP++, 0x8, SEGMENTED_TO_VIRTUAL(dustTextures[idx]));
gSPDisplayList(POLY_XLU_DISP++, gFlareDancerSquareParticleDL);
} }
if (!materialFlag) {
POLY_XLU_DISP = Gfx_SetupDL(POLY_XLU_DISP, SETUPDL_0);
gSPDisplayList(POLY_XLU_DISP++, gFlareDancerDL_7928);
gDPSetEnvColor(POLY_XLU_DISP++, 100, 60, 20, 0);
materialFlag = true;
}
alpha = eff->timer * (255.0f / eff->initialTimer);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 170, 130, 90, alpha);
gDPPipeSync(POLY_XLU_DISP++);
Matrix_Translate(eff->pos.x, eff->pos.y, eff->pos.z, MTXMODE_NEW);
Matrix_ReplaceRotation(&play->billboardMtxF);
Matrix_Scale(eff->scale, eff->scale, 1.0f, MTXMODE_APPLY);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, "../z_en_fw.c", 1229),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
idx = eff->timer * (8.0f / eff->initialTimer);
gSPSegment(POLY_XLU_DISP++, 0x8, SEGMENTED_TO_VIRTUAL(dustTextures[idx]));
gSPDisplayList(POLY_XLU_DISP++, gFlareDancerSquareParticleDL);
} }
CLOSE_DISPS(play->state.gfxCtx, "../z_en_fw.c", 1243); CLOSE_DISPS(play->state.gfxCtx, "../z_en_fw.c", 1243);

View File

@ -129,12 +129,12 @@ void EnGanonMant_Tear(EnGanonMant* this) {
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
if ((0 <= tx && tx < MANT_TEX_WIDTH) && (0 <= ty && ty < MANT_TEX_HEIGHT)) { if ((0 <= tx && tx < MANT_TEX_WIDTH) && (0 <= ty && ty < MANT_TEX_HEIGHT)) {
for (areaX = 0; areaX <= tearAreaSizes[i]; areaX++) { for (areaX = 0; areaX <= tearAreaSizes[i]; areaX++) {
if (1) {}
for (areaY = 0; areaY <= tearAreaSizes[i]; areaY++) { for (areaY = 0; areaY <= tearAreaSizes[i]; areaY++) {
texIdx = (s16)((s16)tx + ((s16)ty * MANT_TEX_WIDTH)) + ((s16)areaX + ((s16)areaY * MANT_TEX_WIDTH)); texIdx = (s16)((s16)tx + ((s16)ty * MANT_TEX_WIDTH)) + ((s16)areaX + ((s16)areaY * MANT_TEX_WIDTH));
if (texIdx < MANT_TEX_WIDTH * MANT_TEX_HEIGHT) { if (texIdx >= MANT_TEX_WIDTH * MANT_TEX_HEIGHT) {
((u16*)gMantTex)[texIdx] = 0; continue;
} }
((u16*)gMantTex)[texIdx] = 0;
} }
} }
} }