From efe2687c10496225492b90187ce2aadba8ac9090 Mon Sep 17 00:00:00 2001 From: nathan Date: Mon, 19 Apr 2021 22:02:49 -0700 Subject: [PATCH] fixed label surfaces not being freed before changes. added elapsed time check before label level change --- AircraftLabel.cpp | 139 +++++++++++++++++++++++++++------------------- AircraftLabel.h | 3 + Label.cpp | 10 +++- View.cpp | 40 ++++++------- View.h | 4 +- 5 files changed, 115 insertions(+), 81 deletions(-) diff --git a/AircraftLabel.cpp b/AircraftLabel.cpp index 57fb740..fb6294c 100644 --- a/AircraftLabel.cpp +++ b/AircraftLabel.cpp @@ -1,15 +1,26 @@ #include "AircraftLabel.h" #include "Aircraft.h" +#include + #include "SDL2/SDL2_gfxPrimitives.h" +using fmilliseconds = std::chrono::duration; + +static std::chrono::high_resolution_clock::time_point now() { + return std::chrono::high_resolution_clock::now(); +} + +static float elapsed(std::chrono::high_resolution_clock::time_point ref) { + return (fmilliseconds {now() - ref}).count(); +} static float sign(float x) { return (x > 0) - (x < 0); } SDL_Rect AircraftLabel::getFullRect(int labelLevel) { - SDL_Rect rect = {x,y,0,0}; + SDL_Rect rect = {static_cast(x),static_cast(y),0,0}; SDL_Rect currentRect; @@ -36,14 +47,18 @@ SDL_Rect AircraftLabel::getFullRect(int labelLevel) { } void AircraftLabel::update() { - char flight[10] = ""; - snprintf(flight,10," %s", p->flight); + char flight[17] = ""; + snprintf(flight,17," %s", p->flight); - flightLabel.setText(flight); + + std::string flightString = flight; + flightString.erase(std::remove_if(flightString.begin(), flightString.end(), isspace), flightString.end()); + + flightLabel.setText(flightString); char alt[10] = ""; if (metric) { - snprintf(alt,10," %dm", (int) (p->altitude / 3.2828)); + snprintf(alt,10," %dm", static_cast(p->altitude / 3.2828)); } else { snprintf(alt,10," %d'", p->altitude); } @@ -52,7 +67,7 @@ void AircraftLabel::update() { char speed[10] = ""; if (metric) { - snprintf(speed,10," %dkm/h", (int) (p->speed * 1.852)); + snprintf(speed,10," %dkm/h", static_cast(p->speed * 1.852)); } else { snprintf(speed,10," %dmph", p->speed); } @@ -117,6 +132,10 @@ float AircraftLabel::calculateDensity(Aircraft *check_p, int labelLevel) { } void AircraftLabel::calculateForces(Aircraft *check_p) { + if(w == 0 || h == 0) { + return; + } + Aircraft *head = check_p; int p_left = x; @@ -125,8 +144,8 @@ void AircraftLabel::calculateForces(Aircraft *check_p) { int p_bottom = y + h; - float boxmid_x = (float)(p_left + p_right) / 2.0f; - float boxmid_y = (float)(p_top + p_bottom) / 2.0f; + float boxmid_x = static_cast(p_left + p_right) / 2.0f; + float boxmid_y = static_cast(p_top + p_bottom) / 2.0f; float offset_x = boxmid_x - p->x; float offset_y = boxmid_y - p->y; @@ -143,19 +162,19 @@ void AircraftLabel::calculateForces(Aircraft *check_p) { // screen edge if(p_left < edge_margin) { - ddx += boundary_force * (float)(edge_margin - p_left); + ddx += boundary_force * static_cast(edge_margin - p_left); } if(p_right > screen_width - edge_margin) { - ddx += boundary_force * (float)(screen_width - edge_margin - p_right); + ddx += boundary_force * static_cast(screen_width - edge_margin - p_right); } if(p_top < edge_margin) { - ddy += boundary_force * (float)(edge_margin - p_top); + ddy += boundary_force * static_cast(edge_margin - p_top); } if(p_bottom > screen_height - edge_margin) { - ddy += boundary_force * (float)(screen_height - edge_margin - p_bottom); + ddy += boundary_force * static_cast(screen_height - edge_margin - p_bottom); } @@ -164,7 +183,6 @@ void AircraftLabel::calculateForces(Aircraft *check_p) { int count = 0; //check against other labels - while(check_p) { if(check_p->addr == p->addr) { check_p = check_p->next; @@ -181,17 +199,17 @@ void AircraftLabel::calculateForces(Aircraft *check_p) { int check_top = check_p->label->y; int check_bottom = check_p->label->y + check_p->label->h; - float icon_x = (float)check_p->x; - float icon_y = (float)check_p->y; + float icon_x = static_cast(check_p->x); + float icon_y = static_cast(check_p->y); - float checkboxmid_x = (float)(check_left + check_right) / 2.0f; - float checkboxmid_y = (float)(check_top + check_bottom) / 2.0f; + float checkboxmid_x = static_cast(check_left + check_right) / 2.0f; + float checkboxmid_y = static_cast(check_top + check_bottom) / 2.0f; float offset_x = boxmid_x - checkboxmid_x; float offset_y = boxmid_y - checkboxmid_y; - float target_length_x = label_dist + (float)(check_p->label->w + w) / 2.0f; - float target_length_y = label_dist + (float)(check_p->label->h + h) / 2.0f; + float target_length_x = label_dist + static_cast(check_p->label->w + w) / 2.0f; + float target_length_y = label_dist + static_cast(check_p->label->h + h) / 2.0f; float x_mag = std::max(0.0f,(target_length_x - fabs(offset_x))); float y_mag = std::max(0.0f,(target_length_y - fabs(offset_y))); @@ -208,8 +226,8 @@ void AircraftLabel::calculateForces(Aircraft *check_p) { offset_x = boxmid_x - check_p->x; offset_y = boxmid_y - check_p->y; - target_length_x = icon_dist + (float)check_p->label->w / 2.0f; - target_length_y = icon_dist + (float)check_p->label->h / 2.0f; + target_length_x = icon_dist + static_cast(check_p->label->w) / 2.0f; + target_length_y = icon_dist + static_cast(check_p->label->h) / 2.0f; x_mag = std::max(0.0f,(target_length_x - fabs(offset_x))); y_mag = std::max(0.0f,(target_length_y - fabs(offset_y))); @@ -227,40 +245,30 @@ void AircraftLabel::calculateForces(Aircraft *check_p) { check_p = check_p -> next; } - // float density_max = calculateDensity(head, labelLevel); - // move away from others ddx += density_force * all_x / count; ddy += density_force * all_y / count; - // label drawlevel hysteresis - - // float density_mult = 100.0f; - // float level_rate = 0.0005f; - - // if(labelLevel < -1.25f + density_mult * density_max) { - // labelLevel += level_rate; - // } else if (labelLevel > 0.5f + density_mult * density_max) { - // labelLevel -= level_rate; - // } - - char buff[100]; - snprintf(buff, sizeof(buff), "%2.2f", labelLevel); - debugLabel.setText(buff); + // char buff[100]; + // snprintf(buff, sizeof(buff), "%2.2f", labelLevel); + // debugLabel.setText(buff); float density_mult = 0.5f; - float level_rate = 0.001f; - - if(labelLevel < 0.8f * density_mult * calculateDensity(head, labelLevel+1)) { - if(labelLevel <= 2) { - labelLevel += level_rate; - } - } else if (labelLevel > 1.2f * density_mult * calculateDensity(head, labelLevel)) { - if(labelLevel >= 0) { - labelLevel -= level_rate; - } - } + float level_rate = 0.25f; + if(elapsed(lastLevelChange) > 1000.0) { + if(labelLevel < 0.8f * density_mult * calculateDensity(head, labelLevel + 1)) { + if(labelLevel <= 2) { + labelLevel += level_rate; + lastLevelChange = now(); + } + } else if (labelLevel > 1.2f * density_mult * calculateDensity(head, labelLevel - 1)) { + if(labelLevel >= 0) { + labelLevel -= level_rate; + lastLevelChange = now(); + } + } + } } void AircraftLabel::applyForces() { @@ -289,6 +297,14 @@ void AircraftLabel::applyForces() { x += dx; y += dy; + if(isnan(x)) { + x = 0; + } + + if(isnan(y)) { + y = 0; + } + // x = p->cx + (int)round(p->ox); // y = p->cy + (int)round(p->oy); } @@ -333,10 +349,13 @@ void AircraftLabel::applyForces() { void AircraftLabel::draw(SDL_Renderer *renderer, bool selected) { - // //don't draw first time - // if(x == 0 || y == 0) { - // return; - // } + if(x == 0 || y == 0) { + return; + } + + // char buff[100]; + // snprintf(buff, sizeof(buff), "%f %f", x, y); + // debugLabel.setText(buff); int totalWidth = 0; int totalHeight = 0; @@ -361,11 +380,11 @@ void AircraftLabel::draw(SDL_Renderer *renderer, bool selected) { opacity = 0; } - if(w != 0) { + if(w != 0 && h != 0 && opacity > 0) { SDL_Color drawColor = style.labelLineColor; - drawColor.a = (int) (255.0f * opacity); + drawColor.a = static_cast(255.0f * opacity); if(selected) { drawColor = style.selectedColor; @@ -405,7 +424,11 @@ void AircraftLabel::draw(SDL_Renderer *renderer, bool selected) { static_cast(exit_y), static_cast(anchor_y)}; - boxRGBA(renderer, x, y, x + w, y + h, 0, 0, 0, 255); + boxRGBA(renderer, x, y, x + w, y + h, 0, 0, 0, drawColor.a); + + // char buff[100]; + // snprintf(buff, sizeof(buff), "%d", drawColor.a); + // debugLabel.setText(buff); bezierRGBA(renderer, vx, vy, 3, 2, drawColor.r, drawColor.g, drawColor.b, drawColor.a); @@ -428,7 +451,7 @@ void AircraftLabel::draw(SDL_Renderer *renderer, bool selected) { // drawSignalMarks(p, x, y); SDL_Color drawColor = style.labelColor; - drawColor.a = (int) (255.0f * opacity); + drawColor.a = static_cast(255.0f * opacity); flightLabel.setColor(drawColor); flightLabel.setPosition(x,y); @@ -443,7 +466,7 @@ void AircraftLabel::draw(SDL_Renderer *renderer, bool selected) { if(labelLevel < 1 || selected) { SDL_Color drawColor = style.subLabelColor; - drawColor.a = (int) (255.0f * opacity); + drawColor.a = static_cast(255.0f * opacity); altitudeLabel.setColor(drawColor); altitudeLabel.setPosition(x,y + totalHeight); @@ -510,4 +533,6 @@ AircraftLabel::AircraftLabel(Aircraft *p, bool metric, int screen_width, int scr altitudeLabel.setFont(font); speedLabel.setFont(font); debugLabel.setFont(font); + + lastLevelChange = now(); } \ No newline at end of file diff --git a/AircraftLabel.h b/AircraftLabel.h index ee15ba3..79c9fa9 100644 --- a/AircraftLabel.h +++ b/AircraftLabel.h @@ -1,6 +1,7 @@ #include #include "SDL2/SDL_ttf.h" +#include #include "Label.h" #include "Style.h" @@ -55,6 +56,8 @@ class AircraftLabel { int screen_width; int screen_height; + std::chrono::high_resolution_clock::time_point lastLevelChange; + /////////// float label_force = 0.001f; diff --git a/Label.cpp b/Label.cpp index d694250..91efb23 100644 --- a/Label.cpp +++ b/Label.cpp @@ -3,13 +3,21 @@ void Label::draw(SDL_Renderer *renderer) { SDL_Rect rect = getRect(); + + if(rect.h == 0 || rect.w == 0) { + return; + } + SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface); SDL_RenderCopy(renderer, texture, NULL, &rect); SDL_DestroyTexture(texture); } - void Label::makeSurface() { + if(surface != NULL) { + SDL_FreeSurface(surface); + } + surface = TTF_RenderUTF8_Solid(font, text.c_str(), color); } diff --git a/View.cpp b/View.cpp index d7e933f..7aadcea 100644 --- a/View.cpp +++ b/View.cpp @@ -180,7 +180,7 @@ void View::latLonFromScreenCoords(float *lat, float *lon, int x, int y) { float scale_factor = (screen_width > screen_height) ? screen_width : screen_height; float dx = maxDist * (x - (screen_width>>1)) / (0.95 * scale_factor * 0.5 ); - float dy = maxDist * (y - (screen_height * CENTEROFFSET)) / (0.95 * scale_factor * 0.5 ); + float dy = maxDist * (y - (screen_height>>1)) / (0.95 * scale_factor * 0.5 ); *lat = 180.0f * dy / (6371.0 * M_PI) + centerLat; *lon = 180.0 * dx / (cos(((*lat + centerLat)/2.0f) * M_PI / 180.0f) * 6371.0 * M_PI) + centerLon; @@ -189,7 +189,7 @@ void View::latLonFromScreenCoords(float *lat, float *lon, int x, int y) { void View::screenCoords(int *outX, int *outY, float dx, float dy) { *outX = (screen_width>>1) + ((dx>0) ? 1 : -1) * screenDist(dx); - *outY = (screen_height * CENTEROFFSET) + ((dy>0) ? -1 : 1) * screenDist(dy); + *outY = (screen_height>>1) + ((dy>0) ? -1 : 1) * screenDist(dy); } int View::outOfBounds(int x, int y) { @@ -380,17 +380,17 @@ void View::drawPlaneOffMap(int x, int y, int *returnx, int *returny, SDL_Color p float arrowWidth = 6.0 * screen_uiscale; float inx = x - (screen_width>>1); - float iny = y - screen_height * CENTEROFFSET; + float iny = y - (screen_height>>1); float outx, outy; outx = inx; outy = iny; - if(abs(inx) > abs(y - (screen_height>>1)) * (float)(screen_width>>1) / (float)(screen_height * CENTEROFFSET)) { //left / right quadrants + if(abs(inx) > abs(y - (screen_height>>1)) * static_cast(screen_width>>1) / static_cast(screen_height>>1)) { //left / right quadrants outx = (screen_width>>1) * ((inx > 0) ? 1.0 : -1.0); outy = (outx) * iny / (inx); } else { // up / down quadrants - outy = screen_height * ((iny > 0) ? 1.0-CENTEROFFSET : -CENTEROFFSET ); + outy = screen_height * ((iny > 0) ? 0.5 : -0.5 ); outx = (outy) * inx / (iny); } @@ -413,20 +413,20 @@ void View::drawPlaneOffMap(int x, int y, int *returnx, int *returny, SDL_Color p // arrow 1 x1 = (screen_width>>1) + outx - 2.0 * arrowWidth * vec[0] + round(-arrowWidth*out[0]); - y1 = (screen_height * CENTEROFFSET) + outy - 2.0 * arrowWidth * vec[1] + round(-arrowWidth*out[1]); + y1 = (screen_height>>1) + outy - 2.0 * arrowWidth * vec[1] + round(-arrowWidth*out[1]); x2 = (screen_width>>1) + outx - 2.0 * arrowWidth * vec[0] + round(arrowWidth*out[0]); - y2 = (screen_height * CENTEROFFSET) + outy - 2.0 * arrowWidth * vec[1] + round(arrowWidth*out[1]); + y2 = (screen_height>>1) + outy - 2.0 * arrowWidth * vec[1] + round(arrowWidth*out[1]); x3 = (screen_width>>1) + outx - arrowWidth * vec[0]; - y3 = (screen_height * CENTEROFFSET) + outy - arrowWidth * vec[1]; + y3 = (screen_height>>1) + outy - arrowWidth * vec[1]; trigonRGBA(renderer, x1, y1, x2, y2, x3, y3, planeColor.r,planeColor.g,planeColor.b,SDL_ALPHA_OPAQUE); // arrow 2 x1 = (screen_width>>1) + outx - 3.0 * arrowWidth * vec[0] + round(-arrowWidth*out[0]); - y1 = (screen_height * CENTEROFFSET) + outy - 3.0 * arrowWidth * vec[1] + round(-arrowWidth*out[1]); + y1 = (screen_height>>1) + outy - 3.0 * arrowWidth * vec[1] + round(-arrowWidth*out[1]); x2 = (screen_width>>1) + outx - 3.0 * arrowWidth * vec[0] + round(arrowWidth*out[0]); - y2 = (screen_height * CENTEROFFSET) + outy - 3.0 * arrowWidth * vec[1] + round(arrowWidth*out[1]); + y2 = (screen_height>>1) + outy - 3.0 * arrowWidth * vec[1] + round(arrowWidth*out[1]); x3 = (screen_width>>1) + outx - 2.0 * arrowWidth * vec[0]; - y3 = (screen_height * CENTEROFFSET) + outy - 2.0 * arrowWidth * vec[1]; + y3 = (screen_height>>1) + outy - 2.0 * arrowWidth * vec[1]; trigonRGBA(renderer, x1, y1, x2, y2, x3, y3, planeColor.r,planeColor.g,planeColor.b,SDL_ALPHA_OPAQUE); *returnx = x3; @@ -510,7 +510,7 @@ void View::drawTrails(int left, int top, int right, int bottom) { return; } - SDL_Color color = lerpColor(style.trailColor, style.planeGoneColor, float(elapsed_s(p->msSeen)) / (float) DISPLAY_ACTIVE); + SDL_Color color = lerpColor(style.trailColor, style.planeGoneColor, static_cast(elapsed_s(p->msSeen)) / DISPLAY_ACTIVE); if(p == selectedAircraft) { color = style.selectedColor; @@ -534,7 +534,7 @@ void View::drawTrails(int left, int top, int right, int bottom) { continue; } - uint8_t colorVal = (uint8_t)floor(127.0 * (age / (float)p->lonHistory.size())); + uint8_t colorVal = (uint8_t)floor(127.0 * (age / static_cast(p->lonHistory.size()))); //thickLineRGBA(renderer, prevX, prevY, currentX, currentY, 2 * screen_uiscale, 255, 255, 255, colorVal); lineRGBA(renderer, prevX, prevY, currentX, currentY, color.r, color.g, color.b, colorVal); @@ -558,9 +558,9 @@ void View::drawScaleBars() lineRGBA(renderer,10+scaleBarDist,8,10+scaleBarDist,16*screen_uiscale,style.scaleBarColor.r, style.scaleBarColor.g, style.scaleBarColor.b, 255); if (metric) { - snprintf(scaleLabel,13,"%dkm", (int)pow(10,scalePower)); + snprintf(scaleLabel,13,"%dkm", static_cast(pow(10,scalePower))); } else { - snprintf(scaleLabel,13,"%dmi", (int)pow(10,scalePower)); + snprintf(scaleLabel,13,"%dmi", static_cast(pow(10,scalePower))); } Label currentLabel; @@ -571,11 +571,11 @@ void View::drawScaleBars() currentLabel.draw(renderer); scalePower++; - scaleBarDist = screenDist((float)pow(10,scalePower)); + scaleBarDist = screenDist(powf(10,scalePower)); } scalePower--; - scaleBarDist = screenDist((float)pow(10,scalePower)); + scaleBarDist = screenDist(powf(10,scalePower)); lineRGBA(renderer,10,10+5*screen_uiscale,10+scaleBarDist,10+5*screen_uiscale, style.scaleBarColor.r, style.scaleBarColor.g, style. scaleBarColor.b, 255); } @@ -907,7 +907,7 @@ void View::drawPlanes() { // lineRGBA(renderer, p->x, p->y, predx, predy, 127,127, 127, 255); // } - planeColor = lerpColor(style.planeColor, style.planeGoneColor, float(elapsed_s(p->msSeen)) / (float) DISPLAY_ACTIVE); + planeColor = lerpColor(style.planeColor, style.planeGoneColor, elapsed_s(p->msSeen) / DISPLAY_ACTIVE); if(p == selectedAircraft) { planeColor = style.selectedColor; @@ -1052,7 +1052,7 @@ void View::drawClick() { if(clickx && clicky) { int radius = .25 * elapsed(clickTime); - int alpha = 128 - (int)(0.5 * elapsed(clickTime)); + int alpha = 128 - static_cast(0.5 * elapsed(clickTime)); if(alpha < 0 ) { alpha = 0; clickx = 0; @@ -1068,7 +1068,7 @@ void View::drawClick() { int boxSize; if(elapsed(clickTime) < 300) { - boxSize = (int)(20.0 * (1.0 - (1.0 - float(elapsed(clickTime)) / 300.0) * cos(sqrt(float(elapsed(clickTime)))))); + boxSize = static_cast(20.0 * (1.0 - (1.0 - elapsed(clickTime) / 300.0) * cos(sqrt(elapsed(clickTime))))); } else { boxSize = 20; } diff --git a/View.h b/View.h index bc29f6c..2bf586d 100644 --- a/View.h +++ b/View.h @@ -44,11 +44,9 @@ //defs - should all move to config file setup #define ROUND_RADIUS 3 //radius of text box corners -#define CENTEROFFSET .5 //vertical offset for middle of screen - #define TRAIL_LENGTH 120 #define TRAIL_TTL 240.0 -#define DISPLAY_ACTIVE 30 +#define DISPLAY_ACTIVE 30.0 #define TRAIL_TTL_STEP 2 #define MIN_MAP_FEATURE 2