load entire levels

This commit is contained in:
Lephenixnoir 2021-08-21 20:57:56 +02:00
parent c664b930f2
commit cacadcb0f4
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
4 changed files with 46 additions and 63 deletions

View File

@ -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;

View File

@ -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();
}

View File

@ -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;
}

View File

@ -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 };