|
|
|
@ -23,6 +23,8 @@ long level_time;
@@ -23,6 +23,8 @@ long level_time;
|
|
|
|
|
|
|
|
|
|
int get_floor_ceiling();
|
|
|
|
|
|
|
|
|
|
struct sg_times_list save_times_lst; |
|
|
|
|
|
|
|
|
|
/* array of all the things in the world and their kinds */ |
|
|
|
|
//world_thing *world;
|
|
|
|
|
|
|
|
|
@ -69,6 +71,116 @@ void level_timer_update(bool reset) {
@@ -69,6 +71,116 @@ void level_timer_update(bool reset) {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int long_comparator(const void *a, const void *b, void *non) { |
|
|
|
|
long A = *(long *)a; |
|
|
|
|
long B = *(long *)b; |
|
|
|
|
|
|
|
|
|
return A - B; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void sort_times(void) { |
|
|
|
|
qsort_r(save_times_lst.times, save_times_lst.size, sizeof(long), long_comparator, NULL); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
long get_best_time(void) { |
|
|
|
|
save_times_lst.sort(); |
|
|
|
|
if (save_times_lst.size > 0)
|
|
|
|
|
return save_times_lst.times[0]; |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int load_score_times(char *filename) { |
|
|
|
|
|
|
|
|
|
char *fn; |
|
|
|
|
char lvl_str[250]; |
|
|
|
|
snprintf(lvl_str, 250, "%d", level); |
|
|
|
|
int fnlen = strlen(filename) + strlen(lvl_str) + 3; |
|
|
|
|
fn = malloc(fnlen); |
|
|
|
|
snprintf(fn, fnlen, "%s-%s", filename, lvl_str); |
|
|
|
|
|
|
|
|
|
printf("%d, lvl_str %s fn %s\n", level, lvl_str, fn); |
|
|
|
|
|
|
|
|
|
FILE *f = fopen(fn, "r"); |
|
|
|
|
// unload existing score times
|
|
|
|
|
if (save_times_lst.times) { |
|
|
|
|
write_times(); |
|
|
|
|
free(save_times_lst.times); |
|
|
|
|
free(save_times_lst.filename); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (f) { |
|
|
|
|
// get file size
|
|
|
|
|
fseek(f, 0L, SEEK_END); |
|
|
|
|
long sz = ftell(f); |
|
|
|
|
fseek(f, 0L, SEEK_SET); |
|
|
|
|
char *text = malloc((sz + 1) * (sizeof(char)));
|
|
|
|
|
|
|
|
|
|
// read file
|
|
|
|
|
fread(text,sizeof(char),sz, f);
|
|
|
|
|
fclose(f); |
|
|
|
|
|
|
|
|
|
int count = 1; |
|
|
|
|
for (int i = 0; i < strlen(text); i++) { |
|
|
|
|
if (text[i] == '\n') { |
|
|
|
|
count++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
long *times = malloc(count * sizeof(long)); |
|
|
|
|
char *saveptr; |
|
|
|
|
|
|
|
|
|
// extract times
|
|
|
|
|
char * token = strtok_r(text, "\n", &saveptr); |
|
|
|
|
int i = 0; |
|
|
|
|
while (token != NULL) { |
|
|
|
|
if (strlen(token) > 2) { |
|
|
|
|
times[i] = atol(token); |
|
|
|
|
i++; |
|
|
|
|
} |
|
|
|
|
token = strtok_r(NULL, "\n", &saveptr); |
|
|
|
|
} |
|
|
|
|
save_times_lst = (struct sg_times_list){.size=i, .capacity = count, .times=times, .sort=sort_times}; |
|
|
|
|
save_times_lst.sort(); |
|
|
|
|
free(text); |
|
|
|
|
} else { |
|
|
|
|
perror("loading times"); |
|
|
|
|
save_times_lst = (struct sg_times_list){.size=0, .capacity = 5, .times=calloc(5, sizeof(long)), .sort=sort_times}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
save_times_lst.filename = fn; |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int add_time(long time) { |
|
|
|
|
if (save_times_lst.capacity == save_times_lst.size + 5) { |
|
|
|
|
long newcap = save_times_lst.capacity * 2; |
|
|
|
|
save_times_lst.times = realloc(save_times_lst.times, newcap); |
|
|
|
|
save_times_lst.capacity = newcap; |
|
|
|
|
} |
|
|
|
|
save_times_lst.times[save_times_lst.size] = time; |
|
|
|
|
save_times_lst.size++; |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int write_times(void) { |
|
|
|
|
FILE *f = fopen(save_times_lst.filename, "w"); |
|
|
|
|
if (!f) { |
|
|
|
|
perror("Saving game"); |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
for (int i = 0; i < save_times_lst.size; i++) { |
|
|
|
|
fprintf(f, "%ld\n", save_times_lst.times[i]); |
|
|
|
|
} |
|
|
|
|
fclose(f); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// collision poly size must be 2x shape_size + 1
|
|
|
|
|
void cast_update_collision_poly(Body *body) { |
|
|
|
|
for (int i=0; i < body->collision_shape_size; i++) { |
|
|
|
@ -587,9 +699,10 @@ void next_level() {
@@ -587,9 +699,10 @@ void next_level() {
|
|
|
|
|
|
|
|
|
|
level *= 7;; |
|
|
|
|
get_floor_ceiling(); |
|
|
|
|
load_score_times("saves/times"); |
|
|
|
|
|
|
|
|
|
v = world.uniques_index[ROOM_W]->room->ceil.items[2]->collision_poly[0]; |
|
|
|
|
v.y -= 30; |
|
|
|
|
v.y -= 15; |
|
|
|
|
|
|
|
|
|
player.physics->position = v; |
|
|
|
|
player.physics->next_position = v; |
|
|
|
@ -1452,6 +1565,9 @@ void startgame(SDL_Renderer * ren) {
@@ -1452,6 +1565,9 @@ void startgame(SDL_Renderer * ren) {
|
|
|
|
|
|
|
|
|
|
level = 31; |
|
|
|
|
|
|
|
|
|
save_times_lst = (struct sg_times_list){}; |
|
|
|
|
load_score_times("saves/times"); |
|
|
|
|
|
|
|
|
|
world = create_world(); |
|
|
|
|
|
|
|
|
|
SDL_GetRendererOutputSize(ren, &width, &height); |
|
|
|
@ -1460,7 +1576,7 @@ void startgame(SDL_Renderer * ren) {
@@ -1460,7 +1576,7 @@ void startgame(SDL_Renderer * ren) {
|
|
|
|
|
|
|
|
|
|
get_floor_ceiling();
|
|
|
|
|
Vect stpos = *world.uniques_index[ROOM_W]->room->ceil.items[2]->collision_poly; |
|
|
|
|
player = get_player(stpos.x + 20, stpos.y - 60); |
|
|
|
|
player = get_player(stpos.x, stpos.y - 15); |
|
|
|
|
world_thing player_world; |
|
|
|
|
|
|
|
|
|
player_world.kind = PLAYER_W; |
|
|
|
@ -1574,8 +1690,7 @@ int step(void) {
@@ -1574,8 +1690,7 @@ int step(void) {
|
|
|
|
|
if (player.physics->position.x > world.uniques_index[ROOM_W]->room |
|
|
|
|
->floor.items[3]->position.x) { |
|
|
|
|
level_timer_update(false); |
|
|
|
|
} else { |
|
|
|
|
} |
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (in_game && !game_paused) { |
|
|
|
|
advance_things(); |
|
|
|
|