load entire levels
This commit is contained in:
parent
c664b930f2
commit
cacadcb0f4
|
@ -78,10 +78,9 @@ typedef struct game {
|
|||
int dead;
|
||||
float time;
|
||||
level_t const *level;
|
||||
rectmeta_t const *current;
|
||||
|
||||
rect_t table[RECT_TABLE_SIZE];
|
||||
int cursor;
|
||||
rect_t *rects;
|
||||
int rect_count;
|
||||
float player_rota;
|
||||
} game_t;
|
||||
|
||||
|
|
95
src/main.c
95
src/main.c
|
@ -7,39 +7,33 @@
|
|||
|
||||
#include <fxlibc/printf.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "duet.h"
|
||||
|
||||
level_t level0 = {
|
||||
.tempo = 1.0,
|
||||
.blocks = (rectmeta_t []){
|
||||
{
|
||||
.time = 0,
|
||||
.shape = Shape_LongBar,
|
||||
.position = Position_Left,
|
||||
.action = Action_Normal
|
||||
},
|
||||
{
|
||||
.time = 1,
|
||||
.shape = Shape_LongBar,
|
||||
.position = Position_Middle,
|
||||
.action = Action_Normal
|
||||
},
|
||||
{
|
||||
.time = 3,
|
||||
.shape = Shape_LongBar,
|
||||
.position = Position_Left,
|
||||
.action = Action_Normal
|
||||
},
|
||||
}
|
||||
};
|
||||
/* Game state */
|
||||
typedef enum {
|
||||
State_Playing,
|
||||
State_Dead,
|
||||
State_Rewind,
|
||||
State_EpisodeCard,
|
||||
State_Finale,
|
||||
} state_t;
|
||||
|
||||
void load_level(game_t *game, level_t const *lv)
|
||||
{
|
||||
memset(game, 0x00, sizeof *game);
|
||||
game->level = lv;
|
||||
game->current = lv->blocks;
|
||||
game->time = -10.0;
|
||||
|
||||
game->rects = realloc(game->rects, lv->block_count * sizeof *game->rects);
|
||||
if(!game->rects)
|
||||
exit(1);
|
||||
for(int i = 0; i < lv->block_count; i++) {
|
||||
game->rects[i].meta = &lv->blocks[i];
|
||||
rect_load(&game->rects[i], &lv->blocks[i]);
|
||||
}
|
||||
game->rect_count = lv->block_count;
|
||||
}
|
||||
|
||||
int strcount(char const *str, int c)
|
||||
|
@ -54,7 +48,7 @@ int main(void)
|
|||
{
|
||||
__printf_enable_fp();
|
||||
|
||||
/* Azur trickz */
|
||||
/* Azur trickz for less tearing */
|
||||
r61524_set(0x010, 0x0010);
|
||||
|
||||
level_t const *story_levels[] = {
|
||||
|
@ -66,6 +60,12 @@ int main(void)
|
|||
game_t game;
|
||||
load_level(&game, story_levels[story_position]);
|
||||
|
||||
state_t state = State_Playing;
|
||||
|
||||
/* Direction of time (with a factor regulating game speed) */
|
||||
float const time_direction_forward = 2.7;
|
||||
float const time_direction_rewind = -5.4;
|
||||
|
||||
volatile int need_frame = 1;
|
||||
int timer = timer_configure(TIMER_ANY, 33000, GINT_CALL_SET(&need_frame));
|
||||
timer_start(timer);
|
||||
|
@ -78,7 +78,13 @@ int main(void)
|
|||
while (need_frame == 0) sleep();
|
||||
need_frame = 0;
|
||||
|
||||
float dt = (1.0 / 30) * lv->tempo * 2.7;
|
||||
float time_direction = lv->tempo * time_direction_forward;
|
||||
if(state == State_Dead)
|
||||
time_direction = 0.0;
|
||||
if(state == State_Rewind)
|
||||
time_direction = time_direction_rewind;
|
||||
|
||||
float dt = (1.0 / 30) * time_direction;
|
||||
game.time += dt;
|
||||
|
||||
/* Input analysis */
|
||||
|
@ -97,35 +103,10 @@ int main(void)
|
|||
rotate_right = true;
|
||||
}
|
||||
|
||||
/* Level generation */
|
||||
|
||||
// Remove rectangles that have passed their lifetime by 4 tempo
|
||||
for(int i = 0; i < game.cursor;) {
|
||||
if(game.time > game.table[i].meta->time + 4)
|
||||
game.table[i] = game.table[--game.cursor];
|
||||
else
|
||||
i++;
|
||||
}
|
||||
|
||||
// Find rectangles that need to be loaded, 10 tempo in advance
|
||||
rectmeta_t const *meta = game.current;
|
||||
while(meta < lv->blocks + lv->block_count) {
|
||||
if(meta - game.current > RECT_TABLE_SIZE - game.cursor)
|
||||
break; /* oops, not enough array space left */
|
||||
if(meta->time - 10 > game.time)
|
||||
break;
|
||||
meta++;
|
||||
}
|
||||
|
||||
// Load everything up to meta
|
||||
while(game.current < meta) {
|
||||
rect_t *r = &game.table[game.cursor++];
|
||||
r->meta = game.current++;
|
||||
rect_load(r, r->meta);
|
||||
}
|
||||
/* Level transitions */
|
||||
|
||||
// End of level
|
||||
if(game.current >= lv->blocks + lv->block_count && game.cursor == 0) {
|
||||
if(game.time >= lv->blocks[lv->block_count-1].time + 5) {
|
||||
if(story_levels[++story_position] == NULL)
|
||||
break;
|
||||
|
||||
|
@ -139,8 +120,8 @@ int main(void)
|
|||
// if(player_collision(&game))
|
||||
// break;
|
||||
|
||||
for(int i = 0; i < game.cursor; i++) {
|
||||
rect_physics(&game.table[i], game.table[i].meta, game.time);
|
||||
for(int i = 0; i < game.rect_count; i++) {
|
||||
rect_physics(&game.rects[i], game.rects[i].meta, game.time);
|
||||
}
|
||||
|
||||
if(rotate_left)
|
||||
|
@ -167,8 +148,8 @@ int main(void)
|
|||
}
|
||||
|
||||
render_player(game.player_rota);
|
||||
for(int i = 0; i < game.cursor; i++)
|
||||
drectoid(&game.table[i], C_WHITE);
|
||||
for(int i = 0; i < game.rect_count; i++)
|
||||
drectoid(&game.rects[i], C_WHITE);
|
||||
dupdate();
|
||||
}
|
||||
|
||||
|
|
|
@ -20,10 +20,10 @@ bool player_collision(game_t const *game)
|
|||
float x1, y1, x2, y2;
|
||||
player_position(game->player_rota, &x1, &y1, &x2, &y2);
|
||||
|
||||
for(int i = 0; i < game->cursor; i++) {
|
||||
if(rect_circle_collide(&game->table[i], x1, y1, PLAYER_SIZE))
|
||||
for(int i = 0; i < game->rect_count; i++) {
|
||||
if(rect_circle_collide(&game->rects[i], x1, y1, PLAYER_SIZE))
|
||||
return true;
|
||||
if(rect_circle_collide(&game->table[i], x2, y2, PLAYER_SIZE))
|
||||
if(rect_circle_collide(&game->rects[i], x2, y2, PLAYER_SIZE))
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -81,6 +81,9 @@ void dtriangle(int x1, int y1, int x2, int y2, int x3, int y3, int color)
|
|||
|
||||
void drectoid(rect_t const *r, int color)
|
||||
{
|
||||
if(r->x - max(r->w,r->h)/2 > DWIDTH || r->x + max(r->w,r->h)/2 < 0)
|
||||
return;
|
||||
|
||||
float x0[4] = { r->w/2, -r->w/2, -r->w/2, r->w/2 };
|
||||
float y0[4] = { -r->h/2, -r->h/2, r->h/2, r->h/2 };
|
||||
|
||||
|
|
Loading…
Reference in New Issue