1
1
Fork 0
Browse Source

level end screen

emscriptem
user 3 years ago
parent
commit
759438a884
  1. 57
      src/draw.c
  2. 1
      src/draw.h
  3. 51
      src/game.c
  4. 9
      src/game.h
  5. 124
      src/main.c
  6. 3
      src/types.h

57
src/draw.c

@ -1,6 +1,7 @@ @@ -1,6 +1,7 @@
#include "draw.h"
#include "game.h"
#include <SDL2/SDL_mutex.h>
#include <SDL2/SDL_render.h>
#include <time.h>
Vect viewport_pos;
@ -280,7 +281,7 @@ void new_update_viewport(Body const * const pl) { @@ -280,7 +281,7 @@ void new_update_viewport(Body const * const pl) {
static double dirchange = 0;
static Vect last_plpos = {};
if (last_plpos.x == 0 && last_plpos.y == 0)
last_plpos = player.physics->position;
last_plpos = pl->position;
static Vect lmove = {};
@ -296,15 +297,16 @@ void new_update_viewport(Body const * const pl) { @@ -296,15 +297,16 @@ void new_update_viewport(Body const * const pl) {
Vect screen_dist = vect_add(in_view(pl->position), vect_scalar(lmove, -1));
static double swap = 0;
if (iv.x > width
|| (iv.x < 0
|| iv.y > height
|| iv.y < 0))
recover = true;
Vect delta = vect_add(vect_scalar(player.physics->position, -1), last_plpos);
Vect delta = vect_add(vect_scalar(pl->position, -1), last_plpos);
double dist_change = vect_mag(delta);
if (true || (recover) //|| vect_mag((Vect){pl->vel.x, 0}) > 0.4
if ((recover) //|| vect_mag((Vect){pl->vel.x, 0}) > 0.4
|| (dist_change > width / 100)) {
if (iv.x < width / 6) {
target = right_pos;
@ -313,7 +315,7 @@ void new_update_viewport(Body const * const pl) { @@ -313,7 +315,7 @@ void new_update_viewport(Body const * const pl) {
}
lmove = target;
last_plpos = player.physics->position;
last_plpos = pl->position;
}
if (recover)
@ -352,11 +354,11 @@ void new_update_viewport(Body const * const pl) { @@ -352,11 +354,11 @@ void new_update_viewport(Body const * const pl) {
v = -v;
// move towards target a set proportion
Vect urgency = vect_add(target, vect_scalar(player.physics->position, -1));
Vect urgency = vect_add(target, vect_scalar(pl->position, -1));
Vect p = vect_add(target, vect_scalar(viewport_pos, -1));
double proportion = (sigmoid(time_delta) / 100);
proportion = 2 * player.physics->vel.x / (width);
proportion = 2 * (pl->vel.x * pl->vel.x / (width));
proportion = proportion < 0 ? -proportion : proportion;
proportion > 0.4 ? proportion = 0.4 : 0;
@ -496,7 +498,7 @@ void draw_text(SDL_Renderer *rend, Vect pos, struct colour colour, char *text) { @@ -496,7 +498,7 @@ void draw_text(SDL_Renderer *rend, Vect pos, struct colour colour, char *text) {
static SDL_Renderer *ren = NULL;
static TTF_Font* font = NULL;
if (!font) {
font = TTF_OpenFont("TerminusTTF.ttf", 18);
font = TTF_OpenFont("TerminusTTF.ttf", 22);
const char *err = SDL_GetError();
if (err) {
printf("%s\n", err);
@ -521,10 +523,45 @@ void draw_text(SDL_Renderer *rend, Vect pos, struct colour colour, char *text) { @@ -521,10 +523,45 @@ void draw_text(SDL_Renderer *rend, Vect pos, struct colour colour, char *text) {
}
int draw_end_screen(SDL_Renderer *ren) {
struct environment scene = get_scene_at(viewport_pos, level);
struct colour bg = scene.colours.bg;
struct colour colour = scene.colours.fg1;
SDL_SetRenderDrawColor(ren, bg.r, bg.g, bg.b,255);
SDL_RenderClear(ren);
int margin = height / 10;
// Vect position = {.x = width - width / 10, .y = height - margin};
int minutes = level_time / 60000;
float seconds = level_time * 0.001;
char time_string[250];
snprintf(time_string, 250, "TIME: %d:%.4f", minutes, seconds);
char * end_str = "Level over.";
char * ct_str = "Press any key to continue.";
char qual_str[250];
snprintf(qual_str, 250, "Physics quality: %d", quality);
Vect position = {.x = width/3, .y = height / 4};
draw_text(ren, position, colour, end_str);
position.y += 40;
draw_text(ren, position, colour, time_string);
position.y += 40;
draw_text(ren, position, colour, qual_str);
position.y += 40;
draw_text(ren, position, colour, ct_str);
SDL_RenderPresent(ren);
return 0;
}
void draw_level_time(SDL_Renderer *ren, struct environment * e) {
int margin = height / 10;
Vect position = {.x = margin, .y = height - margin};
Vect position = {.x = width - width / 10, .y = height - margin};
struct colour colour = e->colours.fg1;
@ -558,8 +595,7 @@ void redraw_buffer(SDL_Renderer * ren) { @@ -558,8 +595,7 @@ void redraw_buffer(SDL_Renderer * ren) {
if (SDL_LockMutex(player.physics->lock) == 0){
lplayer = *player.physics;
new_update_viewport(&lplayer);
SDL_UnlockMutex(player.physics->lock);
update_viewport(&lplayer);
} else {
return;
}
@ -577,6 +613,7 @@ void redraw_buffer(SDL_Renderer * ren) { @@ -577,6 +613,7 @@ void redraw_buffer(SDL_Renderer * ren) {
struct environment scene = get_scene_at(viewport_pos, level);
draw_environment(ren, &scene);
draw_level_time(ren, &scene);
SDL_UnlockMutex(player.physics->lock);
for (int i=0; i < world.items.size; i++) {
world_thing thing;

1
src/draw.h

@ -37,5 +37,6 @@ extern int width, height; @@ -37,5 +37,6 @@ extern int width, height;
void draw_text(SDL_Renderer *ren, Vect pos, struct colour colour, char *text);
int draw_end_screen(SDL_Renderer *ren);
#endif

51
src/game.c

@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
#define FLOOR_THICKNESS 200
#define MAX_ROPE_GRAB_LEN 80000
#define MIN_PHYSICS_STEP 2.0
#define BREAKPOINT *(int *)0 = 1;
@ -14,9 +15,14 @@ GlobWorld world; @@ -14,9 +15,14 @@ GlobWorld world;
player_st *glob_player;
SDL_Renderer *debug_ren;
bool in_game;
bool game_paused;
int level;
int quality = 100;
long level_time;
int get_floor_ceiling();
/* array of all the things in the world and their kinds */
//world_thing *world;
@ -26,7 +32,6 @@ void process_keydown(SDL_Keysym key); @@ -26,7 +32,6 @@ void process_keydown(SDL_Keysym key);
void process_keyup(SDL_Keysym key);
void add_to_world(world_thing thing);
void step(int interval);
void set_motor_timeout(Body *thing, int motorID, uint32_t timeout);
void set_motor_status(Body *thing, int motorID, bool run);
void stop_pull_rope(void);
@ -553,8 +558,9 @@ void destroy_physics_collection(struct physics_collection *s) { @@ -553,8 +558,9 @@ void destroy_physics_collection(struct physics_collection *s) {
free(s->items);
}
int get_floor_ceiling();
void next_level() {
SDL_LockMutex(player.physics->lock);
Vect v;
v.x = 0;
v.y = 0;
@ -588,6 +594,9 @@ void next_level() { @@ -588,6 +594,9 @@ void next_level() {
player.physics->position = v;
player.physics->next_position = v;
quality = 100;
level_timer_update(true);
SDL_UnlockMutex(player.physics->lock);
}
@ -1081,15 +1090,22 @@ void advance_thing(Body * thing) { @@ -1081,15 +1090,22 @@ void advance_thing(Body * thing) {
}
time_delta *= 0.000001; // convert to ms from ns
thing->last_advance_time = now;
// cap the time delta: simulatino will slow down
// printf("delta: %f\n", time_delta);
if (time_delta > 19) {
printf("ERROR too slow: %f\n", time_delta);
time_delta = 19;
quality--;
}
if (time_delta < MIN_PHYSICS_STEP) {
SDL_Delay(MIN_PHYSICS_STEP);
advance_thing(thing);
return;
}
thing->last_advance_time = now;
// collisions
if ((numcols = process_collisions(thing, &translation))) {
/*double check = vect_scalar_projection(translation, thing->vel);*/
@ -1266,15 +1282,16 @@ void advance_thing(Body * thing) { @@ -1266,15 +1282,16 @@ void advance_thing(Body * thing) {
(*thing).vel.y = 0;
}
if (thing->lock) {
SDL_LockMutex(thing->lock);
}
thing->position = thing->next_position;
double oldx = thing->position.x;
double oldy = thing->position.y;
thing->next_position.x += (thing->vel.x * 1/2 * (double)time_delta);
thing->next_position.y += (thing->vel.y * 1/2 * (double)time_delta);
if (thing->lock) {
SDL_LockMutex(thing->lock);
}
thing->position = thing->next_position;
if (!thing->collision_poly[0].y) {
thing->updateCollisionPoly(thing);
@ -1316,7 +1333,6 @@ void get_projectile(Projectile** proj) { @@ -1316,7 +1333,6 @@ void get_projectile(Projectile** proj) {
void advance_things(void) {
int numcols;
Vect translation;
level_timer_update(false);
for (int i = 0; i < world.items.size; i++) {
switch (world.get(i).kind) {
case PLAYER_W :
@ -1458,6 +1474,7 @@ void startgame(SDL_Renderer * ren) { @@ -1458,6 +1474,7 @@ void startgame(SDL_Renderer * ren) {
viewport_pos.y = 0;
level_timer_update(true);
game_paused = 0;
//get_room();
}
@ -1548,17 +1565,21 @@ int get_rand(int seed) { @@ -1548,17 +1565,21 @@ int get_rand(int seed) {
}
void step(int interval) {
int step(void) {
if (player.physics->position.x > world.uniques_index[ROOM_W]->room
->floor.items[world.uniques_index[ROOM_W]->room->floor.numItems - 1]->position.x) {
SDL_Delay(1000);
next_level();
level_timer_update(true);
return 1;
}
if (player.physics->position.x > world.uniques_index[ROOM_W]->room
->floor.items[3]->position.x) {
level_timer_update(false);
} else {
}
advance_things();
if (in_game && !game_paused) {
advance_things();
}
return 0;
}

9
src/game.h

@ -12,6 +12,8 @@ @@ -12,6 +12,8 @@
extern GlobWorld world;
extern int level;
extern bool in_game;
extern int quality;
void handle_input_event(SDL_Event event);
@ -22,12 +24,17 @@ bool get_motor_active(Body *thing, int i); @@ -22,12 +24,17 @@ bool get_motor_active(Body *thing, int i);
int get_rand(int seed);
void next_level();
int step(void);
/* array of all the things in the world and their kinds */
extern void startgame(SDL_Renderer * ren) ;
extern void process_keydown(SDL_Keysym key);
extern void process_keyup(SDL_Keysym key);
extern void step(int interval);
extern player_st player;
extern long level_time;
extern bool game_paused;
#endif

124
src/main.c

@ -1,3 +1,4 @@ @@ -1,3 +1,4 @@
#include <SDL2/SDL_mutex.h>
#include <SDL2/SDL_scancode.h>
#include <stdio.h>
#include <stdlib.h>
@ -15,6 +16,19 @@ @@ -15,6 +16,19 @@
const int screen_width = 800;
const int screen_height = 600;
SDL_sem *resume;
long int *times;
struct sg_times_list {
long *times;
int size;
int capacity;
void (*sort)(void);
};
struct sg_times_list save_times_lst;
struct SDL_Window* make_window(void) {
if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
printf("error initializing SDL: %s\n", SDL_GetError());
@ -30,18 +44,30 @@ struct SDL_Window* make_window(void) { @@ -30,18 +44,30 @@ struct SDL_Window* make_window(void) {
void redraw(struct SDL_Renderer * ren) {
// check time
// redraw if 1/60th of second passed
SDL_RenderClear(ren);
redraw_buffer(ren);
SDL_RenderPresent(ren);
}
int physics_loop(void *ptr) {
while (true) {
step(10);
SDL_Delay(10);
game_paused = 1;
SDL_Delay(1000);
game_paused = 0;
while (1) {
if (step()) {
// display end level screen
game_paused = true;
SDL_Delay(1000);
in_game = false;
SDL_SemWait(resume);
SDL_LockMutex(player.physics->lock);
game_paused = true;
in_game = true;
next_level();
SDL_UnlockMutex(player.physics->lock);
SDL_Delay(1000);
game_paused = 0;
}
}
}
@ -50,7 +76,7 @@ int game(void) { @@ -50,7 +76,7 @@ int game(void) {
LOGLEVEL = DEBUG;
STDOUTLEVEL = DEBUG;
SDL_SetHint( SDL_HINT_RENDER_SCALE_QUALITY, "2" );
//SDL_SetHint( SDL_HINT_RENDER_SCALE_QUALITY, "2" );
logwrite(INFO, "Starting\n");
SDL_Window * win = make_window();
@ -60,12 +86,16 @@ int game(void) { @@ -60,12 +86,16 @@ int game(void) {
queue_for_cleanup(win, WINDOW);
queue_for_cleanup(ren, RENDERER);
in_game = true;
resume = SDL_CreateSemaphore(0);
// IMG_Init(IMG_INIT_PNG | IMG_INIT_JPG);
if (ren == NULL) {
SDL_DestroyWindow(win);
SDL_Quit();
}
TTF_Init();
int close = 0;
@ -75,10 +105,9 @@ int game(void) { @@ -75,10 +105,9 @@ int game(void) {
SDL_Thread *physics_thread;
int ignore;
bool once = true;
startgame(ren);
// physics_thread = SDL_CreateThread(physics_loop, "Physics", (void *)NULL);
physics_thread = SDL_CreateThread(physics_loop, "Physics", (void *)ren);
while (!close) {
@ -92,6 +121,9 @@ int game(void) { @@ -92,6 +121,9 @@ int game(void) {
if (event.key.keysym.scancode == SDL_SCANCODE_ESCAPE) {
return 0;
}
if (!SDL_SemValue(resume)) {
SDL_SemPost(resume);
}
case SDL_KEYUP:
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
@ -99,14 +131,84 @@ int game(void) { @@ -99,14 +131,84 @@ int game(void) {
}
}
/* Redraw Screen */
step(10);
redraw(ren);
// step(10);
if (!in_game) {
draw_end_screen(ren);
} else {
redraw(ren);
}
}
}
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);
}
int load_score_times(char *filename) {
FILE *f = fopen(filename, "r");
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();
} else {
perror("loading times");
save_times_lst = (struct sg_times_list){.size=0, .capacity = 5, .times=calloc(5, sizeof(long)), .sort=sort_times};
}
for (int i = 0; i < save_times_lst.size; i++) {
printf("%ld\n", save_times_lst.times[i]);
}
return 0;
}
long get_best_time(void) {
save_times_lst.sort();
return save_times_lst.times[0];
}
int main (int argc, char** argv) {
load_score_times("savegame");
game();
SDL_Quit();
//empty_cleanup_queue();

3
src/types.h

@ -220,10 +220,9 @@ typedef struct world GlobWorld; @@ -220,10 +220,9 @@ typedef struct world GlobWorld;
enum {
// E_ROOM_WIDTH = 100000,
E_ROOM_WIDTH = 40000,
E_ROOM_WIDTH = 10000,
E_ROOM_RES = 500,
E_ROOM_TILES = E_ROOM_WIDTH / E_ROOM_RES,
};
#endif

Loading…
Cancel
Save