272 lines
6.5 KiB
C

#include "state.h"
static void _state_set(State* self, StateType type);
static void _state_level_tick(State* self, LevelType type);
static void
_state_level_tick(State* self, LevelType type)
{
level_tick(&self->states.level);
if (self->states.level.isPaused)
{
if (control_released(self->ecs->control, CONTROL_RETRY))
_state_set(self, self->type);
if (control_released(self->ecs->control, CONTROL_ESCAPE))
{
level_unpause(&self->states.level);
_state_set(self, STATE_TITLE);
}
}
if (self->states.level.isFinished)
{
if (self->states.level.medal > LEVEL_MEDAL_NONE)
self->levelData[type].status = LEVEL_STATUS_LOCKED + self->states.level.medal;
self->levelData[type].time = self->states.level.timeToMedal;
self->levelData[type].score = self->states.level.score;
if (self->states.level.isComplete && type < LEVEL_FIVE)
{
if (self->levelData[type + 1].status == LEVEL_STATUS_LOCKED)
self->levelData[type + 1].status = LEVEL_STATUS_UNLOCKED;
}
if (type == LEVEL_FIVE && self->states.level.isComplete)
_state_set(self, STATE_CUTSCENE_FINAL);
else
_state_set(self, STATE_TITLE);
}
}
static void
_state_set(State* self, StateType type)
{
state_free(self);
self->type = type;
for (s32 i = 0; i < RENDERER_BUFFER_COUNT; i++)
postprocessing_init(&self->ecs->postprocessing[i], OPAQUE, TRANSPARENT);
switch (self->type)
{
case STATE_TITLE:
title_init(&self->states.title, self->ecs, (LevelData*)self->levelData, LEVEL_COUNT);
break;
case STATE_CUTSCENE_ONE:
cutscene_init(&self->states.cutscene, self->ecs, CUTSCENE_ONE);
break;
case STATE_CUTSCENE_TWO:
cutscene_init(&self->states.cutscene, self->ecs, CUTSCENE_TWO);
break;
case STATE_CUTSCENE_THREE:
cutscene_init(&self->states.cutscene, self->ecs, CUTSCENE_THREE);
break;
case STATE_CUTSCENE_FOUR:
cutscene_init(&self->states.cutscene, self->ecs, CUTSCENE_FOUR);
break;
case STATE_CUTSCENE_FIVE:
cutscene_init(&self->states.cutscene, self->ecs, CUTSCENE_FIVE);
break;
case STATE_CUTSCENE_FINAL:
cutscene_init(&self->states.cutscene, self->ecs, CUTSCENE_FINAL);
break;
case STATE_ENDING:
ending_init(&self->states.ending, self->ecs, ENDING_ONE);
break;
case STATE_ENDING_TWO:
ending_init(&self->states.ending, self->ecs, ENDING_TWO);
break;
case STATE_ENDING_THREE:
ending_init(&self->states.ending, self->ecs, ENDING_THREE);
break;
case STATE_LEVEL_ONE:
level_init(&self->states.level, self->ecs, LEVEL_SETTINGS[LEVEL_ONE], LEVEL_ONE);
break;
case STATE_LEVEL_TWO:
level_init(&self->states.level, self->ecs, LEVEL_SETTINGS[LEVEL_TWO], LEVEL_TWO);
break;
case STATE_LEVEL_THREE:
level_init(&self->states.level, self->ecs, LEVEL_SETTINGS[LEVEL_THREE], LEVEL_THREE);
break;
case STATE_LEVEL_FOUR:
level_init(&self->states.level, self->ecs, LEVEL_SETTINGS[LEVEL_FOUR], LEVEL_FOUR);
break;
case STATE_LEVEL_FIVE:
level_init(&self->states.level, self->ecs, LEVEL_SETTINGS[LEVEL_FIVE], LEVEL_FIVE);
break;
default:
break;
}
}
void
state_init(State* self, ECS* ecs, StateType type)
{
memset(self, '\0', sizeof(State));
self->ecs = ecs;
memcpy(self->levelData, LEVEL_DATA_DEFAULT, sizeof(LEVEL_DATA_DEFAULT));
_state_set(self, type);
}
void
state_free(State* self)
{
switch (self->type)
{
case STATE_TITLE:
title_free(&self->states.title);
break;
case STATE_LEVEL_ONE:
case STATE_LEVEL_TWO:
case STATE_LEVEL_THREE:
case STATE_LEVEL_FOUR:
case STATE_LEVEL_FIVE:
level_free(&self->states.level);
break;
case STATE_CUTSCENE_ONE:
case STATE_CUTSCENE_TWO:
case STATE_CUTSCENE_THREE:
case STATE_CUTSCENE_FOUR:
case STATE_CUTSCENE_FIVE:
case STATE_CUTSCENE_FINAL:
cutscene_free(&self->states.cutscene);
break;
case STATE_ENDING:
case STATE_ENDING_TWO:
case STATE_ENDING_THREE:
ending_free(&self->states.ending);
default:
break;
}
ecs_clear(self->ecs);
}
void
state_change(State* self, StateType type)
{
self->setType = type;
}
void
state_tick(State* self)
{
u32 endingPoints;
endingPoints = 0;
if (self->isChanging)
{
self->isChanging = false;
state_free(self);
memset(&self->states, '\0', sizeof(self->states));
_state_set(self, self->setType);
return;
}
switch (self->type)
{
case STATE_LEVEL_ONE:
_state_level_tick(self, LEVEL_ONE);
break;
case STATE_LEVEL_TWO:
_state_level_tick(self, LEVEL_TWO);
break;
case STATE_LEVEL_THREE:
_state_level_tick(self, LEVEL_THREE);
break;
case STATE_LEVEL_FOUR:
_state_level_tick(self, LEVEL_FOUR);
break;
case STATE_LEVEL_FIVE:
_state_level_tick(self, LEVEL_FIVE);
break;
case STATE_TITLE:
title_tick(&self->states.title);
if (self->states.title.isLevelSelected)
_state_set(self, STATE_CUTSCENE_ONE + self->states.title.levelSelected);
/*
if (control_released(self->ecs->control, CONTROL_CHEAT))
{
memcpy(self->levelData, LEVEL_DATA_CHEAT, sizeof(LEVEL_DATA_CHEAT));
sound_play(&self->ecs->resources->sounds[SOUND_CHEAT]);
_state_set(self, STATE_TITLE);
}
*/
break;
case STATE_CUTSCENE_ONE:
cutscene_tick(&self->states.cutscene);
if (self->states.cutscene.isFinished)
_state_set(self, STATE_LEVEL_ONE);
break;
case STATE_CUTSCENE_TWO:
cutscene_tick(&self->states.cutscene);
if (self->states.cutscene.isFinished)
_state_set(self, STATE_LEVEL_TWO);
break;
case STATE_CUTSCENE_THREE:
cutscene_tick(&self->states.cutscene);
if (self->states.cutscene.isFinished)
_state_set(self, STATE_LEVEL_THREE);
break;
case STATE_CUTSCENE_FOUR:
cutscene_tick(&self->states.cutscene);
if (self->states.cutscene.isFinished)
_state_set(self, STATE_LEVEL_FOUR);
break;
case STATE_CUTSCENE_FIVE:
cutscene_tick(&self->states.cutscene);
if (self->states.cutscene.isFinished)
_state_set(self, STATE_LEVEL_FIVE);
break;
case STATE_CUTSCENE_FINAL:
cutscene_tick(&self->states.cutscene);
if (self->states.cutscene.isFinished)
{
for (s32 i = 0; i < LEVEL_COUNT; i++)
endingPoints += self->levelData[i].status;
if (endingPoints >= LEVEL_STATUS_GOLD * LEVEL_COUNT)
_state_set(self, STATE_ENDING_THREE);
else if (endingPoints >= (LEVEL_STATUS_SILVER * LEVEL_COUNT))
_state_set(self, STATE_ENDING_TWO);
else
_state_set(self, STATE_ENDING);
}
break;
case STATE_ENDING:
case STATE_ENDING_TWO:
case STATE_ENDING_THREE:
ending_tick(&self->states.ending);
if (self->states.ending.isFinished)
_state_set(self, STATE_TITLE);
break;
default:
break;
}
}