|
|
@ -1,4 +1,6 @@ |
|
|
|
#include "draw.h" |
|
|
|
#include "draw.h" |
|
|
|
|
|
|
|
#include <SDL2/SDL_mutex.h> |
|
|
|
|
|
|
|
#include <time.h> |
|
|
|
|
|
|
|
|
|
|
|
Vect viewport_pos; |
|
|
|
Vect viewport_pos; |
|
|
|
int width, height; |
|
|
|
int width, height; |
|
|
@ -8,6 +10,8 @@ int MAX_ONSCREEN_OBJECTS = 99; |
|
|
|
|
|
|
|
|
|
|
|
int num_onscreen = 0; |
|
|
|
int num_onscreen = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
double time_delta = 0; |
|
|
|
|
|
|
|
|
|
|
|
void render_texture_at(struct SDL_Renderer * ren, struct SDL_Texture * texture,int x, int y) { |
|
|
|
void render_texture_at(struct SDL_Renderer * ren, struct SDL_Texture * texture,int x, int y) { |
|
|
|
/* draw a texture at x.y */ |
|
|
|
/* draw a texture at x.y */ |
|
|
|
|
|
|
|
|
|
|
@ -34,6 +38,20 @@ void render_texture_at(struct SDL_Renderer * ren, struct SDL_Texture * texture,i |
|
|
|
/*return (png_image);*/ |
|
|
|
/*return (png_image);*/ |
|
|
|
/*}*/ |
|
|
|
/*}*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
double sigmoid(double x) { |
|
|
|
|
|
|
|
return exp(x) / (exp(x) + 1); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct timespec get_now_d() { |
|
|
|
|
|
|
|
struct timespec now; |
|
|
|
|
|
|
|
clock_gettime(CLOCK_MONOTONIC, &now); |
|
|
|
|
|
|
|
if (now.tv_nsec >= 1000000000) { |
|
|
|
|
|
|
|
now.tv_nsec -= 1000000000; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return now; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Vect in_view(Vect V) { |
|
|
|
Vect in_view(Vect V) { |
|
|
|
Vect ret; |
|
|
|
Vect ret; |
|
|
|
ret.x = V.x -viewport_pos.x; |
|
|
|
ret.x = V.x -viewport_pos.x; |
|
|
@ -58,13 +76,9 @@ void draw_player(SDL_Renderer * ren, int x, int y, bool red) { |
|
|
|
player_rect.w = 20; |
|
|
|
player_rect.w = 20; |
|
|
|
player_rect.h = 20; |
|
|
|
player_rect.h = 20; |
|
|
|
|
|
|
|
|
|
|
|
if (red) { |
|
|
|
struct colour c = get_scene_at(viewport_pos, level).colours.bg; |
|
|
|
SDL_SetRenderDrawColor(ren, 255, 0, 0, 255); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
struct colour c = get_scene_at(viewport_pos, level).colours.bg; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SDL_SetRenderDrawColor(ren, c.r, c.g, c.b, 255); |
|
|
|
SDL_SetRenderDrawColor(ren, c.r, c.g, c.b, 255); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SDL_RenderDrawRect(ren, &player_rect); |
|
|
|
SDL_RenderDrawRect(ren, &player_rect); |
|
|
|
SDL_RenderFillRect(ren, &player_rect); |
|
|
|
SDL_RenderFillRect(ren, &player_rect); |
|
|
@ -73,8 +87,8 @@ void draw_player(SDL_Renderer * ren, int x, int y, bool red) { |
|
|
|
if (!player.physics->strings[i].attached) { |
|
|
|
if (!player.physics->strings[i].attached) { |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
|
Vect B; |
|
|
|
Vect B = {x, y}; |
|
|
|
B = in_view(player.physics->position); |
|
|
|
B = in_view(B); |
|
|
|
Vect E; |
|
|
|
Vect E; |
|
|
|
E = in_view(player.physics->strings[i].end_point); |
|
|
|
E = in_view(player.physics->strings[i].end_point); |
|
|
|
SDL_RenderDrawLine(ren, B.x, B.y, E.x, E.y); |
|
|
|
SDL_RenderDrawLine(ren, B.x, B.y, E.x, E.y); |
|
|
@ -252,24 +266,119 @@ int distance_colour(int x, int y, int x2, int y2, int blackpoint) { |
|
|
|
return frac; |
|
|
|
return frac; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void update_viewport(double x, double y) { |
|
|
|
void new_update_viewport(Body const * const pl) { |
|
|
|
|
|
|
|
int const xmargin = 100; // pixels
|
|
|
|
|
|
|
|
int const ymargin = 100; // pixels
|
|
|
|
|
|
|
|
int const xmovmagin = width / 4; |
|
|
|
|
|
|
|
int const ymovmagin = height / 3; |
|
|
|
|
|
|
|
double const xrange = width - (2 * xmargin); |
|
|
|
|
|
|
|
double const yrange = height - (2 * ymargin); |
|
|
|
|
|
|
|
double const x_max = 2; |
|
|
|
|
|
|
|
double const y_max = 3; |
|
|
|
|
|
|
|
static Vect target = {}; |
|
|
|
|
|
|
|
static double dirchange = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
printf("%f %f\n", pl->vel.x, pl->vel.y); |
|
|
|
|
|
|
|
static Vect lmove = {}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Vect iv = in_view(pl->position); |
|
|
|
|
|
|
|
printf("player pos: %f %f\n", pl->position.x, pl->position.y); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Vect left_pos = {width / 4, height / 2}; |
|
|
|
|
|
|
|
left_pos = vect_add(pl->position, vect_scalar(left_pos, -1)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Vect right_pos = {3 * (width / 4), height / 2}; |
|
|
|
|
|
|
|
right_pos = vect_add(pl->position, vect_scalar(right_pos, -1)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool recover = false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Vect screen_dist = vect_add(in_view(pl->position), vect_scalar(lmove, -1)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (iv.x > width
|
|
|
|
|
|
|
|
|| |
|
|
|
|
|
|
|
(iv.x < 0 |
|
|
|
|
|
|
|
|| iv.y > height |
|
|
|
|
|
|
|
|| iv.y < 0))
|
|
|
|
|
|
|
|
recover = true; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (recover //|| vect_mag((Vect){pl->vel.x, 0}) > 0.4
|
|
|
|
|
|
|
|
|| vect_mag(screen_dist) > width / 3) { |
|
|
|
|
|
|
|
if (pl->vel.x > 0) { |
|
|
|
|
|
|
|
target = left_pos; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
target = right_pos; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
lmove = target; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (recover) |
|
|
|
|
|
|
|
viewport_pos = target; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// emergency
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*if (!(iv.x > width / 3 && iv.x < (2 * (width / 3)))) {*/ |
|
|
|
|
|
|
|
/*if (!(iv.y > height / 3 && iv.y < (2 * (height / 3)))) {*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*if ( true ||*/ |
|
|
|
|
|
|
|
/*( in_view(pl->position).x > xmargin + xrange */ |
|
|
|
|
|
|
|
/*|| in_view(pl->position).x < xmargin)*/ |
|
|
|
|
|
|
|
/*) */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*{*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*double m = (width / 2) / (2.0 * x_max);*/ |
|
|
|
|
|
|
|
/*double x = m * v;*/ |
|
|
|
|
|
|
|
/*target.x = pl->position.x - x;*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*}*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//target.y = pl->position.y - height/2; // + y;
|
|
|
|
|
|
|
|
printf("viewport pos: %f %f\n", iv.x, iv.y); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*}*/ |
|
|
|
|
|
|
|
/*}*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
double v = pl->vel.x; |
|
|
|
|
|
|
|
if (v > x_max)
|
|
|
|
|
|
|
|
v = x_max; |
|
|
|
|
|
|
|
if (v < -x_max)
|
|
|
|
|
|
|
|
v = -x_max; |
|
|
|
|
|
|
|
if (v < 0) |
|
|
|
|
|
|
|
v = -v; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// move towards target a set proportion
|
|
|
|
|
|
|
|
Vect p = vect_add(target, vect_scalar(viewport_pos, -1)); |
|
|
|
|
|
|
|
printf("drawtime: %f", time_delta); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
double proportion = sigmoid(v) * (sigmoid(time_delta) / 300); |
|
|
|
|
|
|
|
printf("prop: %f", proportion); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
proportion > 0.4 ? proportion = 0.4 : 0; |
|
|
|
|
|
|
|
proportion < 0 ? proportion = 0.000001 : 0; |
|
|
|
|
|
|
|
p = vect_scalar(p, proportion); |
|
|
|
|
|
|
|
viewport_pos = vect_add(viewport_pos, p); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void update_viewport(Body *pl) { |
|
|
|
float xmargin = 0.5; |
|
|
|
float xmargin = 0.5; |
|
|
|
float ymargin = 0.2; |
|
|
|
float ymargin = 0.2; |
|
|
|
|
|
|
|
|
|
|
|
if (player.physics->position.x - viewport_pos.x > (1-xmargin) * width) { |
|
|
|
if (pl->position.x - viewport_pos.x > (1-xmargin) * width) { |
|
|
|
viewport_pos.x = - ((1-xmargin) * width - player.physics->position.x); |
|
|
|
viewport_pos.x = - ((1-xmargin) * width - pl->position.x); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (player.physics->position.x - viewport_pos.x < xmargin * width) { |
|
|
|
if (pl->position.x - viewport_pos.x < xmargin * width) { |
|
|
|
viewport_pos.x = -(xmargin * width - player.physics->position.x); |
|
|
|
viewport_pos.x = -(xmargin * width - pl->position.x); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (player.physics->position.y - viewport_pos.y > (1-ymargin) * height) { |
|
|
|
if (pl->position.y - viewport_pos.y > (1-ymargin) * height) { |
|
|
|
viewport_pos.y = -((1-ymargin) * height - player.physics->position.y); |
|
|
|
viewport_pos.y = -((1-ymargin) * height - pl->position.y); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (player.physics->position.y - viewport_pos.y < ymargin * height) { |
|
|
|
if (pl->position.y - viewport_pos.y < ymargin * height) { |
|
|
|
viewport_pos.y = -(ymargin * height - player.physics->position.y); |
|
|
|
viewport_pos.y = -(ymargin * height - pl->position.y); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -393,9 +502,25 @@ void redraw_buffer(SDL_Renderer * ren) { |
|
|
|
/*}*/ |
|
|
|
/*}*/ |
|
|
|
|
|
|
|
|
|
|
|
int col = 0; |
|
|
|
int col = 0; |
|
|
|
|
|
|
|
Body lplayer; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (SDL_LockMutex(player.physics->lock) == 0){ |
|
|
|
|
|
|
|
lplayer = *player.physics; |
|
|
|
|
|
|
|
SDL_UnlockMutex(player.physics->lock); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
new_update_viewport(&lplayer); |
|
|
|
|
|
|
|
static struct timespec last = {}; |
|
|
|
|
|
|
|
static struct timespec now; |
|
|
|
|
|
|
|
now = get_now_d(); |
|
|
|
|
|
|
|
time_delta = now.tv_nsec - last.tv_nsec; |
|
|
|
|
|
|
|
time_delta *= 0.000001; // convert to ms from ns
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
last = now; |
|
|
|
|
|
|
|
|
|
|
|
//SDL_GetMouseState(&newmousex, &newmousey);
|
|
|
|
//SDL_GetMouseState(&newmousex, &newmousey);
|
|
|
|
update_viewport(player.physics->position.x, player.physics->position.y); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct environment scene = get_scene_at(viewport_pos, level); |
|
|
|
struct environment scene = get_scene_at(viewport_pos, level); |
|
|
|
draw_environment(ren, &scene); |
|
|
|
draw_environment(ren, &scene); |
|
|
@ -405,11 +530,6 @@ void redraw_buffer(SDL_Renderer * ren) { |
|
|
|
thing = world.get(i); |
|
|
|
thing = world.get(i); |
|
|
|
|
|
|
|
|
|
|
|
switch (thing.kind) { |
|
|
|
switch (thing.kind) { |
|
|
|
case PLAYER: |
|
|
|
|
|
|
|
draw_player(ren, (*thing.player).physics->position.x, (*thing.player).physics->position.y, thing.player->colliding); |
|
|
|
|
|
|
|
draw_collision_poly(ren, thing.player->physics); |
|
|
|
|
|
|
|
draw_forces(ren, thing.player->physics); |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
case STATIC_WALL_W: |
|
|
|
case STATIC_WALL_W: |
|
|
|
draw_wall(ren, thing.wall); |
|
|
|
draw_wall(ren, thing.wall); |
|
|
|
draw_collision_poly(ren, thing.wall->physics); |
|
|
|
draw_collision_poly(ren, thing.wall->physics); |
|
|
@ -438,6 +558,12 @@ void redraw_buffer(SDL_Renderer * ren) { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
draw_player(ren, lplayer.position.x, lplayer.position.y,
|
|
|
|
|
|
|
|
lplayer.colliding); |
|
|
|
|
|
|
|
draw_collision_poly(ren, &lplayer); |
|
|
|
|
|
|
|
draw_forces(ren, &lplayer); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*if (newmousex != mousex || newmousey != mousey) {*/ /*mousey = newmousey;*/ |
|
|
|
/*if (newmousex != mousex || newmousey != mousey) {*/ /*mousey = newmousey;*/ |
|
|
|
/*mousex = newmousex;*/ |
|
|
|
/*mousex = newmousex;*/ |
|
|
|
/*for (int i = 0; i < 256; i++) {*/ |
|
|
|
/*for (int i = 0; i < 256; i++) {*/ |
|
|
|