@ -1,5 +1,7 @@
@@ -1,5 +1,7 @@
# include "draw.h"
# include "game.h"
# include <SDL2/SDL_mutex.h>
# include <time.h>
Vect viewport_pos ;
int width , height ;
@ -9,6 +11,8 @@ int MAX_ONSCREEN_OBJECTS = 99;
@@ -9,6 +11,8 @@ int MAX_ONSCREEN_OBJECTS = 99;
int num_onscreen = 0 ;
double time_delta = 0 ;
void render_texture_at ( struct SDL_Renderer * ren , struct SDL_Texture * texture , int x , int y ) {
/* draw a texture at x.y */
@ -35,6 +39,20 @@ void render_texture_at(struct SDL_Renderer * ren, struct SDL_Texture * texture,i
@@ -35,6 +39,20 @@ void render_texture_at(struct SDL_Renderer * ren, struct SDL_Texture * texture,i
/*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 ret ;
ret . x = V . x - viewport_pos . x ;
@ -59,13 +77,9 @@ void draw_player(SDL_Renderer * ren, int x, int y, bool red) {
@@ -59,13 +77,9 @@ void draw_player(SDL_Renderer * ren, int x, int y, bool red) {
player_rect . w = 20 ;
player_rect . h = 20 ;
if ( red ) {
SDL_SetRenderDrawColor ( ren , 255 , 0 , 0 , 255 ) ;
} else {
struct colour c = get_scene_at ( viewport_pos , level ) . colours . bg ;
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_RenderFillRect ( ren , & player_rect ) ;
@ -74,8 +88,8 @@ void draw_player(SDL_Renderer * ren, int x, int y, bool red) {
@@ -74,8 +88,8 @@ void draw_player(SDL_Renderer * ren, int x, int y, bool red) {
if ( ! player . physics - > strings [ i ] . attached ) {
continue ;
}
Vect B ;
B = in_view ( player . physics - > position ) ;
Vect B = { x , y } ;
B = in_view ( B ) ;
Vect E ;
E = in_view ( player . physics - > strings [ i ] . end_point ) ;
SDL_RenderDrawLine ( ren , B . x , B . y , E . x , E . y ) ;
@ -253,24 +267,133 @@ int distance_colour(int x, int y, int x2, int y2, int blackpoint) {
@@ -253,24 +267,133 @@ int distance_colour(int x, int y, int x2, int y2, int blackpoint) {
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 ;
static Vect last_plpos = { } ;
if ( last_plpos . x = = 0 & & last_plpos . y = = 0 )
last_plpos = player . physics - > position ;
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 = { 0 , 2 * height / 4 } ;
left_pos = vect_add ( pl - > position , vect_scalar ( left_pos , - 1 ) ) ;
Vect right_pos = { 7 * ( width / 8 ) , 2 * height / 4 } ;
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 ;
Vect delta = vect_add ( vect_scalar ( player . physics - > position , - 1 ) , last_plpos ) ;
double dist_change = vect_mag ( delta ) ;
if ( true | | ( recover ) //|| vect_mag((Vect){pl->vel.x, 0}) > 0.4
| | ( dist_change > width / 100 ) ) {
if ( iv . x < width / 6 ) {
printf ( " RIGHT \n " ) ;
target = right_pos ;
} else {
printf ( " LEFT \n " ) ;
target = left_pos ;
}
lmove = target ;
last_plpos = player . physics - > position ;
}
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 ) ;
printf ( " target pos: %f %f \n " , target . 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 urgency = vect_add ( target , vect_scalar ( player . physics - > position , - 1 ) ) ;
Vect p = vect_add ( target , vect_scalar ( viewport_pos , - 1 ) ) ;
printf ( " drawtime: %f " , time_delta ) ;
double proportion = ( sigmoid ( time_delta ) / 100 ) ;
proportion = 2 * player . physics - > vel . x / ( width ) ;
proportion = proportion < 0 ? - proportion : proportion ;
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 ymargin = 0.2 ;
if ( player . physics - > position . x - viewport_pos . x > ( 1 - xmargin ) * width ) {
viewport_pos . x = - ( ( 1 - xmargin ) * width - player . physics - > position . x ) ;
if ( pl - > position . x - viewport_pos . x > ( 1 - xmargin ) * width ) {
viewport_pos . x = - ( ( 1 - xmargin ) * width - pl - > position . x ) ;
}
if ( player . physics - > position . x - viewport_pos . x < xmargin * width ) {
viewport_pos . x = - ( xmargin * width - player . physics - > position . x ) ;
if ( pl - > position . x - viewport_pos . x < xmargin * width ) {
viewport_pos . x = - ( xmargin * width - pl - > position . x ) ;
}
if ( player . physics - > position . y - viewport_pos . y > ( 1 - ymargin ) * height ) {
viewport_pos . y = - ( ( 1 - ymargin ) * height - player . physics - > position . y ) ;
if ( pl - > position . y - viewport_pos . y > ( 1 - ymargin ) * height ) {
viewport_pos . y = - ( ( 1 - ymargin ) * height - pl - > position . y ) ;
}
if ( player . physics - > position . y - viewport_pos . y < ymargin * height ) {
viewport_pos . y = - ( ymargin * height - player . physics - > position . y ) ;
if ( pl - > position . y - viewport_pos . y < ymargin * height ) {
viewport_pos . y = - ( ymargin * height - pl - > position . y ) ;
}
}
@ -426,8 +549,26 @@ void redraw_buffer(SDL_Renderer * ren) {
@@ -426,8 +549,26 @@ void redraw_buffer(SDL_Renderer * ren) {
/*}*/
/*}*/
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);
update_viewport ( player . physics - > position . x , player . physics - > position . y ) ;
struct environment scene = get_scene_at ( viewport_pos , level ) ;
draw_environment ( ren , & scene ) ;
@ -438,11 +579,6 @@ void redraw_buffer(SDL_Renderer * ren) {
@@ -438,11 +579,6 @@ void redraw_buffer(SDL_Renderer * ren) {
thing = world . get ( i ) ;
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 :
draw_wall ( ren , thing . wall ) ;
draw_collision_poly ( ren , thing . wall - > physics ) ;
@ -471,6 +607,12 @@ void redraw_buffer(SDL_Renderer * ren) {
@@ -471,6 +607,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;*/
/*mousex = newmousex;*/
/*for (int i = 0; i < 256; i++) {*/