diff --git a/src/Core/Entities/PlayerEntity.h b/src/Core/Entities/PlayerEntity.h index f7a95867..1f856a3d 100644 --- a/src/Core/Entities/PlayerEntity.h +++ b/src/Core/Entities/PlayerEntity.h @@ -412,6 +412,7 @@ typedef enum OOCargoQuantity current_cargo; NSPoint cursor_coordinates; + NSPoint chart_cursor_coordinates; NSPoint chart_centre_coordinates; // where we want the chart centre to be - used for smooth transitions NSPoint target_chart_centre; @@ -679,7 +680,7 @@ typedef enum - (NSPoint) cursor_coordinates; - (NSPoint) chart_centre_coordinates; - (OOScalar) chart_zoom; -- (NSPoint) chart_centre_for_zoom: (OOScalar) zoom; +- (NSPoint) adjusted_chart_centre; - (OORouteType) ANAMode; - (Random_Seed) system_seed; diff --git a/src/Core/Entities/PlayerEntity.m b/src/Core/Entities/PlayerEntity.m index 2efa7514..8e50da4b 100644 --- a/src/Core/Entities/PlayerEntity.m +++ b/src/Core/Entities/PlayerEntity.m @@ -571,12 +571,73 @@ static GLfloat sBaseMass = 0.0; } -- (NSPoint) chart_centre_for_zoom: (OOScalar) zoom +- (NSPoint) adjusted_chart_centre { - NSPoint p; - p.x = chart_centre_coordinates.x + (128.0 - chart_centre_coordinates.x) * (zoom - 1.0) / (CHART_MAX_ZOOM - 1.0); - p.y = chart_centre_coordinates.y + (128.0 - chart_centre_coordinates.y) * (zoom - 1.0) / (CHART_MAX_ZOOM - 1.0); - return p; + NSPoint acc; // adjusted chart centre + double scroll_pos; // cursor coordinate at which we'd want to scoll chart in the direction we're currently considering + double ecc; // chart centre coordinate we'd want if the cursor was on the edge of the galaxy in the current direction + + // When fully zoomed in we want to centre chart on chart_centre_coordinates. When zoomed out we want the chart centred on + // (128.0, 128.0) so the galaxy fits the screen width. For intermediate zoom we interpolate. + acc.x = chart_centre_coordinates.x + (128.0 - chart_centre_coordinates.x) * (chart_zoom - 1.0) / (CHART_MAX_ZOOM - 1.0); + acc.y = chart_centre_coordinates.y + (128.0 - chart_centre_coordinates.y) * (chart_zoom - 1.0) / (CHART_MAX_ZOOM - 1.0); + + // If the cursor is out of the centre non-scrolling part of the screen adjust the chart centre. If the cursor is just at scroll_pos + // we want to return the chart centre as it is, but if it's at the edge of the galaxy we want the centre positioned so the cursor is + // at the edge of the screen + if (chart_cursor_coordinates.x - acc.x <= -CHART_SCROLL_AT_X*chart_zoom) + { + scroll_pos = acc.x - CHART_SCROLL_AT_X*chart_zoom; + ecc = CHART_WIDTH_AT_MAX_ZOOM*chart_zoom / 2.0; + if (scroll_pos <= 0) + { + acc.x = ecc; + } + else + { + acc.x = ((scroll_pos-chart_cursor_coordinates.x)*ecc + chart_cursor_coordinates.x*acc.x)/scroll_pos; + } + } + else if (chart_cursor_coordinates.x - acc.x >= CHART_SCROLL_AT_X*chart_zoom) + { + scroll_pos = acc.x + CHART_SCROLL_AT_X*chart_zoom; + ecc = 256.0 - CHART_WIDTH_AT_MAX_ZOOM*chart_zoom / 2.0; + if (scroll_pos >= 256.0) + { + acc.x = ecc; + } + else + { + acc.x = ((chart_cursor_coordinates.x-scroll_pos)*ecc + (256.0 - chart_cursor_coordinates.x)*acc.x)/(256.0 - scroll_pos); + } + } + if (chart_cursor_coordinates.y - acc.y <= -CHART_SCROLL_AT_Y*chart_zoom) + { + scroll_pos = acc.y - CHART_SCROLL_AT_Y*chart_zoom; + ecc = CHART_HEIGHT_AT_MAX_ZOOM*chart_zoom / 2.0; + if (scroll_pos <= 0) + { + acc.y = ecc; + } + else + { + acc.y = ((scroll_pos-chart_cursor_coordinates.y)*ecc + chart_cursor_coordinates.y*acc.y)/scroll_pos; + } + } + else if (chart_cursor_coordinates.y - acc.y >= CHART_SCROLL_AT_Y*chart_zoom) + { + scroll_pos = acc.y + CHART_SCROLL_AT_Y*chart_zoom; + ecc = 256.0 - CHART_HEIGHT_AT_MAX_ZOOM*chart_zoom / 2.0; + if (scroll_pos >= 256.0) + { + acc.y = ecc; + } + else + { + acc.y = ((chart_cursor_coordinates.y-scroll_pos)*ecc + (256.0 - chart_cursor_coordinates.y)*acc.y)/(256.0 - scroll_pos); + } + } + return acc; } @@ -971,6 +1032,7 @@ static GLfloat sBaseMass = 0.0; cursor_coordinates.x = [coord_vals oo_unsignedCharAtIndex:0]; cursor_coordinates.y = [coord_vals oo_unsignedCharAtIndex:1]; } + chart_cursor_coordinates = cursor_coordinates; keyStringValue = [dict oo_stringForKey:@"found_system_seed"]; found_system_seed = (keyStringValue != nil) ? RandomSeedFromString(keyStringValue) : kNilRandomSeed; @@ -1736,6 +1798,7 @@ static GLfloat sBaseMass = 0.0; chart_centre_coordinates = galaxy_coordinates; target_chart_centre = chart_centre_coordinates; cursor_coordinates = galaxy_coordinates; + chart_cursor_coordinates = cursor_coordinates; chart_zoom = 1.0; target_chart_zoom = 1.0; saved_chart_zoom = 1.0; diff --git a/src/Core/Entities/PlayerEntityControls.m b/src/Core/Entities/PlayerEntityControls.m index bbae17cd..963d65b9 100644 --- a/src/Core/Entities/PlayerEntityControls.m +++ b/src/Core/Entities/PlayerEntityControls.m @@ -1734,7 +1734,7 @@ static NSTimeInterval time_last_frame; double vadjust = 80; double hscale = MAIN_GUI_PIXEL_WIDTH / (64.0 * chart_zoom); double vscale = MAIN_GUI_PIXEL_HEIGHT / (128.0 * chart_zoom); - NSPoint centre = [self chart_centre_for_zoom: chart_zoom]; + NSPoint centre = [self adjusted_chart_centre]; cursor_coordinates.x = OOClamp_0_max_f(centre.x + (maus.x * MAIN_GUI_PIXEL_WIDTH) / hscale, 256.0); cursor_coordinates.y = OOClamp_0_max_f(centre.y + (maus.y * MAIN_GUI_PIXEL_HEIGHT + vadjust) / vscale, 256.0); if (gui_screen == GUI_SCREEN_LONG_RANGE_CHART) @@ -1857,25 +1857,11 @@ static NSTimeInterval time_last_frame; cursor_coordinates.x = target_system_seed.d; cursor_coordinates.y = target_system_seed.b; } - if (cursor_coordinates.x - target_chart_centre.x <= -CHART_SCROLL_AT_X*chart_zoom) - { - target_chart_centre.x = cursor_coordinates.x + CHART_SCROLL_AT_X*chart_zoom; - } - else if (cursor_coordinates.x - target_chart_centre.x >= CHART_SCROLL_AT_X*chart_zoom) - { - target_chart_centre.x = cursor_coordinates.x - CHART_SCROLL_AT_X*chart_zoom; - } - if (cursor_coordinates.y - target_chart_centre.y <= -CHART_SCROLL_AT_Y*chart_zoom) - { - target_chart_centre.y = cursor_coordinates.y + CHART_SCROLL_AT_Y*chart_zoom; - } - else if (cursor_coordinates.y - target_chart_centre.y >= CHART_SCROLL_AT_Y*chart_zoom) - { - target_chart_centre.y = cursor_coordinates.y - CHART_SCROLL_AT_Y*chart_zoom; - } chart_centre_coordinates.x = (3.0*chart_centre_coordinates.x + target_chart_centre.x)/4.0; chart_centre_coordinates.y = (3.0*chart_centre_coordinates.y + target_chart_centre.y)/4.0; chart_zoom = (3.0*chart_zoom + target_chart_zoom)/4.0; + chart_cursor_coordinates.x = (3.0*chart_cursor_coordinates.x + cursor_coordinates.x)/4.0; + chart_cursor_coordinates.y = (3.0*chart_cursor_coordinates.y + cursor_coordinates.y)/4.0; if (cursor_moving) [self setGuiToChartScreenFrom: gui_screen]; // update graphics cursor_moving = moving; } diff --git a/src/Core/GuiDisplayGen.m b/src/Core/GuiDisplayGen.m index 812e7927..d76565be 100644 --- a/src/Core/GuiDisplayGen.m +++ b/src/Core/GuiDisplayGen.m @@ -1533,7 +1533,7 @@ static OOTextureSprite *NewTextureSpriteWithDescriptor(NSDictionary *descriptor) return; OOScalar zoom = [player chart_zoom]; - NSPoint chart_centre_coordinates = [player chart_centre_for_zoom: zoom]; + NSPoint chart_centre_coordinates = [player adjusted_chart_centre]; NSPoint galaxy_coordinates = [player galaxy_coordinates]; NSPoint cursor_coordinates = [player cursor_coordinates]; OOLongRangeChartMode chart_mode = [player longRangeChartMode];