#include #include #include #include #include #include #include #include #include #include #include #include #include "hash.h" #include "structure.h" #include "base.h" #include "generation.h" #include "display.h" void updateRenderer(SDL_Renderer* renderer) { //printf("E"); SDL_RenderPresent(renderer); } void resetRenderer(SDL_Renderer* renderer) { SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); SDL_RenderClear(renderer); } void drawRectToRenderer(SDL_Renderer* renderer, SDL_Rect* rect, int R, int G, int B, int A) { SDL_SetRenderDrawColor(renderer, R, G, B, A); SDL_RenderFillRect(renderer, rect); } void placeRectToRenderer(SDL_Renderer* renderer, int X, int Y, int W, int H, int R, int G, int B, int A) { SDL_Rect rect; rect.x = X; rect.y = Y; rect.w = W; rect.h = H; SDL_SetRenderDrawColor(renderer, R, G, B, A); SDL_RenderFillRect(renderer, &rect); } void drawLineWithThicc(SDL_Renderer* renderer, int width, int x1, int x2, int y1, int y2, int R, int G, int B, int A) { // draws line with width (native SDL cannot do that) double theta = 0.0; double seglen = distance_pt(x1, x2, y1, y2); while(theta < 1.0) { placeRectToRenderer(renderer, convex_seg(x1, x2, theta)-width/2, convex_seg(y1, y2, theta)-width/2, width, width, R, G, B, A); theta += 1 / seglen; } } void drawLineWithThiccGradient(SDL_Renderer* renderer, int start_width, int end_width, int x1, int x2, int y1, int y2, int R, int G, int B, int A) { // draws line with width ; // width goes from start_width to end_with in a linear way double theta = 0.0; double seglen = distance_pt(x1, x2, y1, y2); while(theta < 1.0) { int width = convex_seg(start_width, end_width, theta) ; placeRectToRenderer(renderer, convex_seg(x1, x2, theta)-width/2, convex_seg(y1, y2, theta)-width/2, width, width, R, G, B, A); theta += 1 / seglen; } } void drawDigitToRenderer(SDL_Renderer* renderer, imgs data, int digit, int X, int Y, int W, int H) { if(digit == -727) { SDL_Rect rect; rect.x = X; rect.y = Y; rect.w = W; rect.h = H; SDL_Texture* texture = data.arr[10]; SDL_RenderCopy(renderer, texture, NULL, &rect); } else if (!(0 <= digit && digit <= 9)) { fprintf(stderr, "Illegal digit : '%d'.\n", digit); exit(1); } else { SDL_Rect rect; rect.x = X; rect.y = Y; rect.w = W; rect.h = H; SDL_Texture* texture = data.arr[digit]; SDL_RenderCopy(renderer, texture, NULL, &rect); } } void drawCharToRenderer(SDL_Renderer* renderer, imgs data, char c, int X, int Y, int W, int H) { if ((int)c >= 97 && (int)c <= 122) { SDL_Rect rect; rect.x = X; rect.y = Y; rect.w = W; rect.h = H; SDL_Texture* texture = data.arr[(int)c - 97]; SDL_RenderCopy(renderer, texture, NULL, &rect); } } void drawNumberToRenderer(SDL_Renderer* renderer, imgs data, int n, int X, int Y, int W, int H, int Woffset) { if(n == 0) { drawDigitToRenderer(renderer, data, 0, X + W, Y, W, H); } else if(n > 0) { int toDraw = 0, remaining = n, nIter = ln_baseN(n, 10); while(nIter != 0) { toDraw = remaining%10; remaining = remaining / 10; drawDigitToRenderer(renderer, data, toDraw, X + (W-Woffset)*nIter, Y, W, H); nIter--; } } else { int toDraw = 0, remaining = -n, nIter = ln_baseN(-n, 10); drawDigitToRenderer(renderer, data, -727, X, Y, W, H); while(nIter != 0) { toDraw = remaining%10; remaining = remaining / 10; drawDigitToRenderer(renderer, data, toDraw, X + (W-Woffset)*nIter, Y, W, H); nIter--; } } } void drawStringToRenderer(SDL_Renderer* renderer, imgs data, char* s, int X, int Y, int W, int H) { int k = 0 ; while(s[k] != '\0') { drawCharToRenderer(renderer, data, s[k], X + W*k, Y, W, H); k += 1; } } void rescale(int* xm, int* xM, int* ym, int* yM, double scale) { *xm = (int)((*xm - __width__/2) * scale + __width__/2) ; *xM = (int)((*xM - __width__/2) * scale + __width__/2) ; *ym = (int)((*ym - __height__/2) * scale + __height__/2) ; *yM = (int)((*yM - __height__/2) * scale + __height__/2) ; } bool isOnLeft(chunk* ch, int x, int y) { return (x == 0 || unpack_coord(ch->chdata.lines, x-1, y)); } bool isOnRight(chunk* ch, int x, int y) { return (x == 7 || unpack_coord(ch->chdata.lines, x+1, y)); } bool isOnTop(chunk* ch, int x, int y) { return (y == 0 || unpack_coord(ch->chdata.lines, x, y-1)); } bool isOnBottom(chunk* ch, int x, int y) { return (y == 7 || unpack_coord(ch->chdata.lines, x, y+1)); } bool isPtInPoly(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4, int xp, int yp) { // (x2 - x1) * (yp - y1) - (xp - x1) * (y2 - y1) ; int v1 = (x2 - x1) * (yp - y1) - (xp - x1) * (y2 - y1) ; int v2 = (x3 - x2) * (yp - y2) - (xp - x2) * (y3 - y2) ; int v3 = (x4 - x3) * (yp - y3) - (xp - x3) * (y4 - y3) ; int v4 = (x1 - x4) * (yp - y4) - (xp - x4) * (y1 - y4) ; return (sign(v1) == sign(v2) && sign(v2) == sign(v3) && sign(v3) == sign(v4)); } static int total ; void fillQuadPoly(SDL_Renderer* renderer, int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) { int ymin = min(min(y1, y2), min(y3, y4)); int ymax = max(max(y1, y2), max(y3, y4)); int xmin = min(min(x1, x2), min(x3, x4)); int xmax = max(max(x1, x2), max(x3, x4)); for(int h = ymin; h <= ymax; h++) { for(int w = xmin; w <= xmax; w++) { if(isPtInPoly(x1, y1, x2, y2, x3, y3, x4, y4, w, h)) { SDL_RenderDrawPoint(renderer, w, h); } } }; /*double step = max_db(distance_pt(x1, y1, x2, y2), distance_pt(x3, y3, x4, y4)); double theta = 0.0 ; while(theta <= 1.0) { total += 1 ; drawLineWithThicc(renderer, 2, convex_seg(x1, x2, theta), convex_seg(x4, x3, theta), convex_seg(y1, y2, theta), convex_seg(y4, y3, theta), 255, 192, 255, SDL_ALPHA_OPAQUE); theta += 1.0 / step; }*/ /*total += (ymax-ymin)*(xmax-xmin) ; printf("T = %d\n", total);*/ drawLineWithThicc(renderer, 2, x1, x2, y1, y2, 32, 32, 32, SDL_ALPHA_OPAQUE); drawLineWithThicc(renderer, 2, x2, x3, y2, y3, 32, 32, 32, SDL_ALPHA_OPAQUE); drawLineWithThicc(renderer, 2, x3, x4, y3, y4, 32, 32, 32, SDL_ALPHA_OPAQUE); drawLineWithThicc(renderer, 2, x4, x1, y4, y1, 32, 32, 32, SDL_ALPHA_OPAQUE); } void drawChunkToRenderer(SDL_Renderer* renderer, chunk* ch, int xmin, int xmax, int ymin, int ymax, bool period) { if(ch->draw_id != draw_par || !period) { ch->draw_id = draw_par ; for(int i = 0; i < 8; i++) { uint8_t cur = ch->chdata.lines[i] ; for(int j = 0; j < 8; j++) { int cux = 50*(8*ch->chx + j); int cuy = 50*(8*ch->chy + i); int cux2 = 50*(8*ch->chx + j+1); int cuy2 = 50*(8*ch->chy + i+1); if(true) { if(cur%2 == 1) { int nxmin = to_int((to_double(cux) - to_double(xmin)) * to_double(__width__)) / (to_double(xmax) - to_double(xmin)) ; int nymin = to_int((to_double(cuy) - to_double(ymin)) * to_double(__height__)) / (to_double(ymax) - to_double(ymin)) ; int nxmax = to_int((to_double(cux2) - to_double(xmin)) * to_double(__width__)) / (to_double(xmax) - to_double(xmin)) ; int nymax = to_int((to_double(cuy2) - to_double(ymin)) * to_double(__height__)) / (to_double(ymax) - to_double(ymin)) ; uint8_t R = 255 - 63 * ((abs(ch->chx) + abs(ch->chy))%2 == 0) ; uint8_t G = 255 ; uint8_t B = 255 - 63 * ((abs(ch->chx) + abs(ch->chy))%2 == 1) ; int sxmin = nxmin ; int sxmax = nxmax ; int symin = nymin ; int symax = nymax ; rescale(&nxmin, &nxmax, &nymin, &nymax, 1.5); if(period) { if(!isOnLeft(ch, i, j) && (8*ch->chy + i) >= (8*player_cy + player_y)) { // North SDL_SetRenderDrawColor(renderer, R/2, G/2, B/2, SDL_ALPHA_OPAQUE); fillQuadPoly(renderer, nxmin, nymin, sxmin, symin, sxmax, symin, nxmax, nymin); } if(!isOnBottom(ch, i, j) && (8*ch->chx + j) <= (8*player_cx + player_x)) { // West SDL_SetRenderDrawColor(renderer, R/2, G/2, B/2, SDL_ALPHA_OPAQUE); fillQuadPoly(renderer, nxmax, nymax, sxmax, symax, sxmax, symin, nxmax, nymin); } if(!isOnRight(ch, i, j) && (8*ch->chy + i) <= (8*player_cy + player_y)) { // South SDL_SetRenderDrawColor(renderer, R/2, G/2, B/2, SDL_ALPHA_OPAQUE); fillQuadPoly(renderer, nxmax, nymax, sxmax, symax, sxmin, symax, nxmin, nymax); } if(!isOnTop(ch, i, j) && (8*ch->chx + j) >= (8*player_cx + player_x)) { // East SDL_SetRenderDrawColor(renderer, R/2, G/2, B/2, SDL_ALPHA_OPAQUE); fillQuadPoly(renderer, nxmin, nymin, sxmin, symin, sxmin, symax, nxmin, nymax); } } else { SDL_SetRenderDrawColor(renderer, R, G, B, SDL_ALPHA_OPAQUE); placeRectToRenderer(renderer, nxmin, nymin, nxmax - nxmin, nymax - nymin, 32, 32, 32, SDL_ALPHA_OPAQUE); placeRectToRenderer(renderer, nxmin+1, nymin+1, nxmax - nxmin -2, nymax - nymin -2, R, G, B, SDL_ALPHA_OPAQUE); } }; cur = cur / 2 ; } } } } } void drawHashToRenderer(SDL_Renderer* renderer, int chx, int chy, int xmin, int xmax, int ymin, int ymax, int distx, int disty) { if(distx < render_distance && disty < render_distance) { chunk* todraw = gridGet(map, chx, chy) ; if(todraw == NULL) { fprintf(stderr, "NO (%d, %d)\n", chx, chy); exit(1); }; if(distx != render_distance -1 && !gridMem(map, chx+1, chy)) { generate_chunk_all(chx+1, chy); }; if(distx != render_distance -1 && !gridMem(map, chx-1, chy)) { generate_chunk_all(chx-1, chy); }; if(disty != render_distance -1 && !gridMem(map, chx, chy+1)) { generate_chunk_all(chx, chy+1); }; if(disty != render_distance -1 && !gridMem(map, chx, chy-1)) { generate_chunk_all(chx, chy-1); }; drawHashToRenderer(renderer, chx+1, chy, xmin, xmax, ymin, ymax, distx+1, disty); drawHashToRenderer(renderer, chx-1, chy, xmin, xmax, ymin, ymax, distx+1, disty); drawHashToRenderer(renderer, chx, chy+1, xmin, xmax, ymin, ymax, distx, disty+1); drawHashToRenderer(renderer, chx, chy-1, xmin, xmax, ymin, ymax, distx, disty+1); drawChunkToRenderer(renderer, todraw, xmin, xmax, ymin, ymax, false); } } void drawMapToRenderer(SDL_Renderer* renderer, int xmin, int xmax, int ymin, int ymax) { drawHashToRenderer(renderer, player_cx, player_cy, xmin, xmax, ymin, ymax, 0, 0); placeRectToRenderer(renderer, __width__ /2 - 5*zoom/100, __height__ /2 - 5*zoom/100, 10*zoom/100, 10*zoom/100, 255, 255, 32, SDL_ALPHA_OPAQUE); } void drawMapToRendererV2(SDL_Renderer* renderer, int xmin, int xmax, int ymin, int ymax) { for(int i = 0; i < (2*render_distance+1)*(2*render_distance+1); i++) { if(!gridMem(map, player_cx+sorted_x[i], player_cy + sorted_y[i])) { generate_chunk_all(player_cx+sorted_x[i], player_cy + sorted_y[i]); } chunk* todraw = gridGet(map, player_cx+sorted_x[i], player_cy + sorted_y[i]) ; drawChunkToRenderer(renderer, todraw, xmin, xmax, ymin, ymax, true); drawChunkToRenderer(renderer, todraw, xmin, xmax, ymin, ymax, false); } placeRectToRenderer(renderer, __width__ /2 - 5*zoom/100, __height__ /2 - 5*zoom/100, 10*zoom/100, 10*zoom/100, 255, 255, 32, SDL_ALPHA_OPAQUE); }