You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
309 lines
9.3 KiB
309 lines
9.3 KiB
#include "draw.h" |
|
#include "vect.h" |
|
|
|
/* generic rendering functions */ |
|
int MAX_ONSCREEN_OBJECTS = 99; |
|
|
|
int num_onscreen = 0; |
|
|
|
void render_texture_at(struct SDL_Renderer * ren, struct SDL_Texture * texture,int x, int y) { |
|
/* draw a texture at x.y */ |
|
|
|
SDL_Rect destination; |
|
destination.x = x; |
|
destination.y = y; |
|
|
|
SDL_QueryTexture(texture, NULL, NULL, &destination.w, &destination.h); |
|
|
|
SDL_RenderCopy(ren, texture, NULL, &destination); |
|
} |
|
|
|
SDL_Texture * load_image(SDL_Renderer * ren, char fname[]) { |
|
/* Load an image into a texture */ |
|
|
|
SDL_Surface * surface = IMG_Load(fname) ; |
|
if(!surface) { |
|
printf("IMG_Load: %s\n", IMG_GetError()); |
|
// handle error |
|
} |
|
|
|
SDL_Texture * png_image = SDL_CreateTextureFromSurface(ren, surface); |
|
cleanup(surface, SURFACE); |
|
return (png_image); |
|
} |
|
|
|
Vect in_view(Vect V) { |
|
Vect ret; |
|
ret.x = V.x -viewport_pos.x; |
|
ret.y = V.y -viewport_pos.y; |
|
return ret; |
|
} |
|
|
|
/* Game Specific rendering functions */ |
|
void draw_player(SDL_Renderer * ren, int x, int y, bool red) { |
|
logwrite(DEBUG, "Drawing player\n"); |
|
// translate to viewport |
|
|
|
Vect V; |
|
V.x = x; V.y = y; |
|
V = in_view(V); |
|
|
|
/* draw the player as a coloured rect */ |
|
SDL_Rect player_rect; |
|
|
|
player_rect.x = V.x -10; |
|
player_rect.y = V.y -10; |
|
|
|
player_rect.w = 20; |
|
player_rect.h = 20; |
|
|
|
if (red) { |
|
SDL_SetRenderDrawColor(ren, 255, 0, 0, 255); |
|
} else { |
|
SDL_SetRenderDrawColor(ren, 120, 85, 188, 255); |
|
} |
|
SDL_RenderDrawRect(ren, &player_rect); |
|
SDL_RenderFillRect(ren, &player_rect); |
|
SDL_SetRenderDrawColor(ren, 0,0,0, 255); |
|
} |
|
|
|
void draw_floor(SDL_Renderer *ren, FloorPoly *poly) { |
|
SDL_Point left; |
|
SDL_Point right; |
|
left.x = poly->left.x - viewport_pos.x; |
|
|
|
if (left.x > width) { |
|
return; |
|
} |
|
|
|
right.x = poly->right.x - viewport_pos.x; |
|
if (right.x < 0) { |
|
return; |
|
} |
|
|
|
left.y = poly->left.y - viewport_pos.y; |
|
right.y = poly->right.y - viewport_pos.y; |
|
|
|
SDL_SetRenderDrawColor(ren, 100,100,100, 255); |
|
double m = (double)(right.y - left.y) / (double)(right.x - left.x); |
|
double c = (double)left.y - ((double)left.x * m); |
|
for (int i = left.x; i <= right.x; i++) { |
|
int y = (int)(m * i + c); |
|
SDL_RenderDrawLine(ren, i, y, i, height); |
|
} |
|
SDL_SetRenderDrawColor(ren, 0,0,0, 255); |
|
|
|
} |
|
|
|
// draw collision poly |
|
void draw_collision_poly(SDL_Renderer* ren, Body *body) { |
|
if (!SHOWCOLLISION) { |
|
return; |
|
} |
|
|
|
if (body->colliding) { |
|
SDL_SetRenderDrawColor(ren, 255, 0, 0, 255); |
|
} else { |
|
SDL_SetRenderDrawColor(ren, 0, 255, 0, 255); |
|
} |
|
|
|
if (body->collision_poly_size == 1) { |
|
SDL_Rect dot; |
|
Vect V; |
|
V.x = body->collision_poly[0].x; |
|
V.y = body->collision_poly[0].y; |
|
Vect T = in_view(V); |
|
dot.x = T.x; |
|
dot.y = T.y; |
|
dot.w = 4; |
|
dot.h = 4; |
|
SDL_RenderDrawRect(ren, &dot); |
|
SDL_RenderFillRect(ren, &dot); |
|
} else if (body->collision_poly_size == 2) { |
|
int x_st = body->collision_poly[0].x -viewport_pos.x; |
|
int y_st = body->collision_poly[0].y -viewport_pos.y; |
|
int x_en = body->collision_poly[1].x -viewport_pos.x; |
|
int y_en = body->collision_poly[1].y -viewport_pos.y; |
|
SDL_RenderDrawLine(ren, x_st, y_st, x_en, y_en); |
|
} else if (body->collision_poly_size > 2) { |
|
int x_st = body->collision_poly[0].x -viewport_pos.x; |
|
int y_st = body->collision_poly[0].y -viewport_pos.y; |
|
int x_en, y_en; |
|
for (int i = 1; i < body->collision_poly_size; i++) { |
|
x_en = body->collision_poly[i].x -viewport_pos.x; |
|
y_en = body->collision_poly[i].y -viewport_pos.y; |
|
SDL_RenderDrawLine(ren, x_st, y_st, x_en, y_en); |
|
x_st = x_en; |
|
y_st = y_en; |
|
} |
|
x_en = body->collision_poly[0].x-viewport_pos.x; |
|
y_en = body->collision_poly[0].y-viewport_pos.y; |
|
SDL_RenderDrawLine(ren, x_st, y_st, x_en, y_en); |
|
} |
|
SDL_SetRenderDrawColor(ren, 0,0,0, 255); |
|
} |
|
|
|
// draw indicator of forces acting on an object |
|
void draw_forces(SDL_Renderer *ren, Body *body) { |
|
if (!SHOWFORCES) { |
|
return; |
|
} |
|
Vect start; |
|
start.x = (int)body->position.x -viewport_pos.x; |
|
start.y = (int)body->position.y -viewport_pos.y; |
|
|
|
Vect F; |
|
for (int i = 0; i < body->num_motors; i++) { |
|
if (body->motors[i].timeout < SDL_GetTicks()) { |
|
continue; |
|
} |
|
F.x += body->motors[i].x; |
|
F.y += body->motors[i].y; |
|
Vect end = vect_add(start, F); |
|
SDL_SetRenderDrawColor(ren, 255,0,0, 255); |
|
SDL_RenderDrawLine(ren, start.x, start.y, start.x, end.y); |
|
SDL_SetRenderDrawColor(ren, 0,0,255, 255); |
|
SDL_RenderDrawLine(ren, start.x, start.y, end.x, start.y); |
|
} |
|
|
|
SDL_SetRenderDrawColor(ren, 0,0,0, 255); |
|
} |
|
|
|
void draw_wall(SDL_Renderer *ren, Wall *wall) { |
|
SDL_SetRenderDrawColor(ren, 120, 85, 188, 255); |
|
int x_st, x_en, y_st, y_en; |
|
x_st = wall->nodes[0].x + wall->physics->position.x -viewport_pos.x; |
|
y_st = wall->nodes[0].y + wall->physics->position.y -viewport_pos.y; |
|
for (int i = 1; i < wall->numNodes; i++) { |
|
x_en = wall->nodes[i].x + wall->physics->position.x -viewport_pos.x; |
|
y_en = wall->nodes[i].y + wall->physics->position.y -viewport_pos.y; |
|
printf("wall: %d %d %d %d\n", x_st, y_st, x_en, y_en); |
|
SDL_RenderDrawLine(ren, x_st, y_st, x_en, y_en); |
|
x_st = x_en; |
|
y_st = y_en; |
|
} |
|
x_en = wall->nodes[0].x + wall->physics->position.x -viewport_pos.x; |
|
y_en = wall->nodes[0].y + wall->physics->position.y -viewport_pos.y; |
|
SDL_RenderDrawLine(ren, x_st, y_st, x_en, y_en); |
|
|
|
SDL_SetRenderDrawColor(ren, 0,0,0, 255); |
|
} |
|
|
|
int distance_colour(int x, int y, int x2, int y2, int blackpoint) { |
|
|
|
int dist = (int) sqrt((x2 - x)*(x2 - x) + (y2 - y)*(y2 - y) ); |
|
|
|
if (dist == 0) { |
|
return 255; |
|
} |
|
if (dist > blackpoint) { |
|
return 0; |
|
} |
|
|
|
int frac = blackpoint / dist; |
|
|
|
// int frac = 255 * (int) sin((double)dist / blackpoint); |
|
if (frac > 255) { |
|
return 255; |
|
} |
|
|
|
return frac; |
|
} |
|
|
|
void update_viewport(double x, double y) { |
|
float xmargin = 0.26; |
|
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 (player.physics->position.x - viewport_pos.x < xmargin * width) { |
|
viewport_pos.x = -(xmargin * width - player.physics->position.x); |
|
} |
|
|
|
if (player.physics->position.y - viewport_pos.y > (1-ymargin) * height) { |
|
viewport_pos.y = -((1-ymargin) * height - player.physics->position.y); |
|
} |
|
|
|
if (player.physics->position.y - viewport_pos.y < ymargin * height) { |
|
viewport_pos.y = -(ymargin * height - player.physics->position.y); |
|
} |
|
} |
|
|
|
|
|
void redraw_buffer(SDL_Renderer * ren) { |
|
static int mousex = 0; |
|
static int mousey = 0; |
|
static int newmousex = 0; |
|
static int newmousey = 0; |
|
static SDL_Point *bgPixels[256]; |
|
static int numpixels[256]; |
|
|
|
/*if (!width && !height) {*/ |
|
/*for (int i = 0; i < 256; i++) {*/ |
|
/*bgPixels[i] = malloc(sizeof(SDL_Point) * width * height);*/ |
|
/*memset(bgPixels[i], 0, sizeof(SDL_Point) * width * height);*/ |
|
/*memset(numpixels, 0, (sizeof(int) * 256));*/ |
|
/*}*/ |
|
/*}*/ |
|
|
|
int col = 0; |
|
|
|
//SDL_GetMouseState(&newmousex, &newmousey); |
|
update_viewport(player.physics->position.x, player.physics->position.y); |
|
|
|
for (int i=0; i<things_in_world; i++) { |
|
world_thing thing; |
|
thing = world[i]; |
|
printf("draw thing: %d\n, no %d of %d\n", thing.kind, thing.nid, things_in_world); |
|
|
|
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); |
|
break; |
|
case STATIC_WALL_W: |
|
draw_wall(ren, thing.wall); |
|
draw_collision_poly(ren, thing.wall->physics); |
|
break; |
|
case FLOOR: |
|
for (int i = 0; i < thing.floor->numPolys; i++) { |
|
draw_floor(ren, &thing.floor->polys[i]); |
|
draw_collision_poly(ren, thing.floor->polys[i].physics); |
|
|
|
} |
|
} |
|
} |
|
|
|
/*if (newmousex != mousex || newmousey != mousey) {*/ /*mousey = newmousey;*/ |
|
/*mousex = newmousex;*/ |
|
/*for (int i = 0; i < 256; i++) {*/ |
|
/*memset(bgPixels[i], 0, sizeof(SDL_Point) * width * height);*/ |
|
/*memset(numpixels, 0, (sizeof(int) * 256));*/ |
|
/*}*/ |
|
/*for (int i=0; i < width; i++) {*/ |
|
/*for (int j = 0; j < height; j++) {*/ |
|
/*col = distance_colour(i, j, mousex, mousey, 10000);*/ |
|
|
|
/*SDL_Point *row = bgPixels[col];*/ |
|
/*SDL_Point point;*/ |
|
/*point.x = i;*/ |
|
/*point.y = j;*/ |
|
/*row[numpixels[col]] = point;*/ |
|
/*numpixels[col] += 1;*/ |
|
|
|
/*}*/ |
|
/*}*/ |
|
/*}*/ |
|
|
|
/*for (int i = 0; i < 255; i++) {*/ |
|
/*SDL_Point *row = bgPixels[i];*/ |
|
/*col = i;*/ |
|
/*SDL_SetRenderDrawColor(ren, col, col, col, 255);*/ |
|
/*SDL_RenderDrawPoints(ren, row, numpixels[i]);*/ |
|
/*}*/ |
|
|
|
|
|
}
|
|
|