time parameterization + forced rotation direction
This commit is contained in:
parent
0498f076ba
commit
d933944322
|
@ -0,0 +1,4 @@
|
|||
* Tighter than the original?
|
||||
* Count number of turns, with optimal
|
||||
* Add performance counters
|
||||
* Check if level tempo is accounted for
|
Binary file not shown.
Before Width: | Height: | Size: 401 B After Width: | Height: | Size: 6.7 KiB |
|
@ -10,7 +10,7 @@
|
|||
#include <math.h>
|
||||
|
||||
//---
|
||||
// Level strucutres
|
||||
// Level structures
|
||||
//---
|
||||
|
||||
typedef enum {
|
||||
|
@ -149,7 +149,8 @@ extern level_t level5, level6, level7, level8;
|
|||
extern level_t level9, level10, level11, level12;
|
||||
extern level_t level13, level14, level15, level16;
|
||||
extern level_t level17, level18, level19, level20;
|
||||
extern level_t level21, level22;
|
||||
extern level_t level21, level22, level23, level24;
|
||||
extern level_t level25, level26, level27, level28;
|
||||
|
||||
extern episode_t episodes[];
|
||||
extern int episode_count;
|
||||
|
|
90
src/main.c
90
src/main.c
|
@ -54,8 +54,15 @@ episode_t episodes[] = {
|
|||
&level22,
|
||||
},
|
||||
},
|
||||
{
|
||||
.name = "guilt",
|
||||
.level_count = 1,
|
||||
.levels = (level_t *[]) {
|
||||
&level22, // TODO
|
||||
},
|
||||
},
|
||||
};
|
||||
int episode_count = 4;
|
||||
int episode_count = sizeof(episodes) / sizeof(episodes[0]);
|
||||
|
||||
void load_level(game_t *game, level_t const *lv)
|
||||
{
|
||||
|
@ -80,6 +87,20 @@ int strcount(char const *str, int c)
|
|||
return count;
|
||||
}
|
||||
|
||||
/* Round player rotation to closest multiple of M_PI */
|
||||
float rpr(float rota)
|
||||
{
|
||||
if(fabs(rota) <= M_PI_2)
|
||||
return 0;
|
||||
return (rota < 0) ? -M_PI : M_PI;
|
||||
}
|
||||
|
||||
/* Forced player rotation to go back to an even position */
|
||||
float fpr(float rota, float duration)
|
||||
{
|
||||
return (rpr(rota) - rota) / duration;
|
||||
}
|
||||
|
||||
void game_loop(int current_episode, int current_level)
|
||||
{
|
||||
game_t game;
|
||||
|
@ -89,19 +110,34 @@ void game_loop(int current_episode, int current_level)
|
|||
|
||||
state_t state = State_Playing;
|
||||
|
||||
if(current_level == 0) {
|
||||
state = State_EpisodeTransition;
|
||||
game.time_episode_transition = 0;
|
||||
game.time = -14.0;
|
||||
}
|
||||
|
||||
/* Direction of time (with a factor regulating game speed) */
|
||||
float const time_direction_forward = 2.7;
|
||||
float const time_direction_rewind = -25;
|
||||
/* Level time to start (negative to leave time before blocks arrive) */
|
||||
float const LEVEL_START = -14.0;
|
||||
/* Level time until which message is shown */
|
||||
float const MESSAGE_END = -5.0;
|
||||
/* Duration of death pause (seconds) */
|
||||
float const DEATH_PAUSE_DURATION = 0.7;
|
||||
/* Level time to restarting playing at after rewind */
|
||||
float const REWIND_END = -5.0;
|
||||
/* Duration of level transitions (seconds) */
|
||||
float const TRANSITION_DURATION = 1.0;
|
||||
/* Duration of episode transitions (seconds)
|
||||
Warning: overlaps with pre-level, will lock player if too long x_x */
|
||||
float const EPISODE_TRANSITION_DURATION = 3.0;
|
||||
|
||||
volatile int need_frame = 1;
|
||||
int timer = timer_configure(TIMER_ANY, 33000, GINT_CALL_SET(&need_frame));
|
||||
if(timer >= 0) timer_start(timer);
|
||||
/* Frame duration in real time */
|
||||
float const FRAME_DURATION = 1.0 / 30;
|
||||
|
||||
if(current_level == 0) {
|
||||
state = State_EpisodeTransition;
|
||||
game.time_episode_transition = 0;
|
||||
game.time = LEVEL_START;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
level_t const *lv = game.level;
|
||||
|
@ -116,38 +152,37 @@ void game_loop(int current_episode, int current_level)
|
|||
time_direction = time_direction_rewind;
|
||||
|
||||
if(state == State_Dead) {
|
||||
game.time_dead += (1.0 / 30);
|
||||
if(game.time_dead >= 0.7) {
|
||||
game.time_dead += FRAME_DURATION;
|
||||
if(game.time_dead >= DEATH_PAUSE_DURATION) {
|
||||
game.time_dead = 0;
|
||||
game.forced_player_rota = game.player_rota / (game.time + 5.0);
|
||||
game.forced_player_rota = fpr(game.player_rota,
|
||||
REWIND_END - game.time);
|
||||
state = State_Rewind;
|
||||
}
|
||||
continue;
|
||||
continue; /* Pause effect */
|
||||
}
|
||||
if(state == State_Transition) {
|
||||
time_direction = 1.0;
|
||||
game.time_transition += (1.0 / 30);
|
||||
if(game.time_transition >= 1.0) {
|
||||
game.time_transition += FRAME_DURATION;
|
||||
if(game.time_transition >= TRANSITION_DURATION) {
|
||||
game.time_transition = 0;
|
||||
game.player_rota = 0;
|
||||
game.forced_player_rota = 0;
|
||||
state = State_Playing;
|
||||
}
|
||||
}
|
||||
if(state == State_EpisodeTransition) {
|
||||
time_direction = 1.0;
|
||||
game.time_episode_transition += (1.0 / 30);
|
||||
if(game.time_episode_transition >= 1.0) {
|
||||
game.player_rota = 0;
|
||||
game.time_episode_transition += FRAME_DURATION;
|
||||
if(game.time_episode_transition >= TRANSITION_DURATION) {
|
||||
game.forced_player_rota = 0;
|
||||
}
|
||||
if(game.time_episode_transition >= 3.0) {
|
||||
if(game.time_episode_transition >= EPISODE_TRANSITION_DURATION) {
|
||||
game.time_episode_transition = 0;
|
||||
state = State_Playing;
|
||||
}
|
||||
}
|
||||
|
||||
float dt = (1.0 / 30) * time_direction;
|
||||
float dt = FRAME_DURATION * time_direction;
|
||||
game.time += dt;
|
||||
|
||||
/* Input analysis */
|
||||
|
@ -193,23 +228,24 @@ void game_loop(int current_episode, int current_level)
|
|||
if(changed_episode) {
|
||||
state = State_EpisodeTransition;
|
||||
game.time_episode_transition = 0;
|
||||
game.forced_player_rota = -game.player_rota / 1.0;
|
||||
game.time = -13.0;
|
||||
game.forced_player_rota = fpr(game.player_rota,
|
||||
TRANSITION_DURATION);
|
||||
game.time = LEVEL_START;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
state = State_Transition;
|
||||
game.time_transition = 0;
|
||||
game.forced_player_rota = -game.player_rota / 1.0;
|
||||
game.forced_player_rota = fpr(game.player_rota,
|
||||
TRANSITION_DURATION);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// End of rewind
|
||||
if(state == State_Rewind && game.time <= -5.0) {
|
||||
game.time = -5.0;
|
||||
game.player_rota = 0.0;
|
||||
game.forced_player_rota = 0.0;
|
||||
if(state == State_Rewind && game.time <= REWIND_END) {
|
||||
game.time = REWIND_END;
|
||||
game.forced_player_rota = 0;
|
||||
state = State_Playing;
|
||||
continue;
|
||||
}
|
||||
|
@ -255,7 +291,7 @@ void game_loop(int current_episode, int current_level)
|
|||
dma_memcpy(gint_vram + 396*(40*j), gint_vram, 396*2*lines);
|
||||
}
|
||||
|
||||
if(state == State_Playing && game.time < -4.0 && lv->message) {
|
||||
if(state == State_Playing && game.time < MESSAGE_END && lv->message) {
|
||||
int x = DWIDTH/2 + 8 * (strcount(lv->message, '\n') + 1);
|
||||
|
||||
/* Split at newlines */
|
||||
|
|
|
@ -136,6 +136,9 @@ void rect_physics(rect_t *r, rectmeta_t const *meta, float absolute_time)
|
|||
float speeding_period = fminf(2.0, fmaxf(0.0, time + 6.0));
|
||||
r->x -= RECT_SPEED * speeding_period;
|
||||
}
|
||||
else if(meta->action == Action_FadeOut) {
|
||||
// TODO
|
||||
}
|
||||
else if(meta->action == Action_OuterRotateLeft) {
|
||||
float vr = 0.7; /* rad/tempo */
|
||||
r->r = time * vr;
|
||||
|
@ -144,4 +147,14 @@ void rect_physics(rect_t *r, rectmeta_t const *meta, float absolute_time)
|
|||
float vr = 0.7; /* rad/tempo */
|
||||
r->r = -time * vr;
|
||||
}
|
||||
else if(meta->action == Action_Slide) {
|
||||
// TODO
|
||||
}
|
||||
else if(meta->action == Action_Speed2) {
|
||||
/* Double speed permanently */
|
||||
// TODO
|
||||
}
|
||||
else if(meta->action == Action_Speed3) {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue