LCOV - code coverage report
Current view: top level - Core - GuiDisplayGen.m (source / functions) Hit Total Coverage
Test: coverxygen.info Lines: 2 19 10.5 %
Date: 2025-05-28 07:50:54 Functions: 0 0 -

          Line data    Source code
       1           0 : /*
       2             : 
       3             : GuiDisplayGen.m
       4             : 
       5             : Oolite
       6             : Copyright (C) 2004-2013 Giles C Williams and contributors
       7             : 
       8             : This program is free software; you can redistribute it and/or
       9             : modify it under the terms of the GNU General Public License
      10             : as published by the Free Software Foundation; either version 2
      11             : of the License, or (at your option) any later version.
      12             : 
      13             : This program is distributed in the hope that it will be useful,
      14             : but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             : GNU General Public License for more details.
      17             : 
      18             : You should have received a copy of the GNU General Public License
      19             : along with this program; if not, write to the Free Software
      20             : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
      21             : MA 02110-1301, USA.
      22             : 
      23             : */
      24             : 
      25             : #import "GuiDisplayGen.h"
      26             : #import "Universe.h"
      27             : #import "GameController.h"
      28             : #import "PlayerEntity.h"
      29             : #import "PlayerEntityControls.h"
      30             : #import "OOTextureSprite.h"
      31             : #import "ResourceManager.h"
      32             : #import "OOSound.h"
      33             : #import "OOStringExpander.h"
      34             : #import "OOStringParsing.h"
      35             : #import "HeadUpDisplay.h"
      36             : #import "OOCollectionExtractors.h"
      37             : #import "OOTexture.h"
      38             : #import "OOJavaScriptEngine.h"
      39             : #import "PlayerEntityStickProfile.h"
      40             : #import "OOSystemDescriptionManager.h"
      41             : 
      42           0 : OOINLINE BOOL RowInRange(OOGUIRow row, NSRange range)
      43             : {
      44             :         return ((int)range.location <= row && row < (int)(range.location + range.length));
      45             : }
      46             : 
      47             : @interface GuiDisplayGen (Internal)
      48             : 
      49           0 : - (void) drawGLDisplay:(GLfloat)x :(GLfloat)y :(GLfloat)z :(GLfloat) alpha;
      50             : 
      51           0 : - (void) drawCrossHairsWithSize:(GLfloat) size x:(GLfloat)x y:(GLfloat)y z:(GLfloat)z;
      52           0 : - (void) drawStarChart:(GLfloat)x :(GLfloat)y :(GLfloat)z :(GLfloat) alpha :(BOOL) compact;
      53           0 : - (void) drawSystemMarkers:(NSArray *)marker atX:(GLfloat)x andY:(GLfloat)y andZ:(GLfloat)z withAlpha:(GLfloat)alpha andScale:(GLfloat)scale;
      54           0 : - (void) drawSystemMarker:(NSDictionary *)marker atX:(GLfloat)x andY:(GLfloat)y andZ:(GLfloat)z withAlpha:(GLfloat)alpha andScale:(GLfloat)scale;
      55             : 
      56           1 : - (void) drawEquipmentList:(NSArray *)eqptList z:(GLfloat)z;
      57           0 : - (void) drawAdvancedNavArrayAtX:(float)x y:(float)y z:(float)z alpha:(float)alpha usingRoute:(NSDictionary *) route optimizedBy:(OORouteType) optimizeBy zoom: (OOScalar) zoom;
      58             : 
      59             : @end
      60             : 
      61             : 
      62             : @implementation GuiDisplayGen
      63             : 
      64           0 : static BOOL _refreshStarChart = NO;
      65             : 
      66             : - (id) init
      67             : {
      68             :         if ((self = [super init]))
      69             :         {
      70             :                 size_in_pixels  = NSMakeSize(MAIN_GUI_PIXEL_WIDTH, MAIN_GUI_PIXEL_HEIGHT);
      71             :                 n_columns               = GUI_DEFAULT_COLUMNS;
      72             :                 n_rows                  = GUI_DEFAULT_ROWS;
      73             :                 pixel_row_center = size_in_pixels.width / 2;
      74             :                 pixel_row_height = MAIN_GUI_ROW_HEIGHT;
      75             :                 pixel_row_start = MAIN_GUI_PIXEL_ROW_START;             // first position down the page...
      76             :                 max_alpha = 1.0;
      77             :                 
      78             :                 pixel_text_size = NSMakeSize(0.9f * pixel_row_height, pixel_row_height);        // main gui has 18x20 characters
      79             :                 
      80             :                 pixel_title_size = NSMakeSize(pixel_row_height * 1.75f, pixel_row_height * 1.5f);
      81             :                 
      82             :                 int stops[6] = {0, 192, 256, 320, 384, 448};
      83             :                 unsigned i;
      84             :                 
      85             :                 rowRange = NSMakeRange(0,n_rows);
      86             :                 
      87             :                 rowText =   [[NSMutableArray alloc] initWithCapacity:n_rows];   // alloc retains
      88             :                 rowKey =        [[NSMutableArray alloc] initWithCapacity:n_rows];   // alloc retains
      89             :                 rowColor =      [[NSMutableArray alloc] initWithCapacity:n_rows];   // alloc retains
      90             :                 
      91             :                 for (i = 0; i < n_rows; i++)
      92             :                 {
      93             :                         [rowText addObject:@"."];
      94             :                         [rowKey addObject:[NSString stringWithFormat:@"%d",i]];
      95             :                         [rowColor addObject:[OOColor yellowColor]];
      96             :                         rowPosition[i].x = 0.0f;
      97             :                         rowPosition[i].y = size_in_pixels.height - (pixel_row_start + i * pixel_row_height);
      98             :                         rowAlignment[i] = GUI_ALIGN_LEFT;
      99             :                 }
     100             :                 
     101             :                 for (i = 0; i < n_columns; i++)
     102             :                 {
     103             :                         tabStops[i] = stops[i];
     104             :                 }
     105             :                 
     106             :                 title = @"";
     107             :                 
     108             :                 textColor = [[OOColor yellowColor] retain];
     109             :                 
     110             :                 drawPosition = make_vector(0.0f, 0.0f, 640.0f);
     111             :                 
     112             :                 backgroundSpecial = GUI_BACKGROUND_SPECIAL_NONE;
     113             : 
     114             :                 guiUserSettings = [[ResourceManager dictionaryFromFilesNamed:@"gui-settings.plist" inFolder:@"Config" andMerge:YES] retain];
     115             :         }
     116             :         return self;
     117             : }
     118             : 
     119             : 
     120             : - (id) initWithPixelSize:(NSSize)gui_size
     121             :                                  columns:(int)gui_cols 
     122             :                                         rows:(int)gui_rows 
     123             :                            rowHeight:(int)gui_row_height
     124             :                                 rowStart:(int)gui_row_start
     125             :                                    title:(NSString*)gui_title
     126             : {
     127             :         self = [super init];
     128             :                 
     129             :         size_in_pixels  = gui_size;
     130             :         n_columns               = gui_cols;
     131             :         n_rows                  = gui_rows;
     132             :         pixel_row_center = size_in_pixels.width / 2;
     133             :         pixel_row_height = gui_row_height;
     134             :         pixel_row_start = gui_row_start;                // first position down the page...
     135             :         max_alpha = 1.0;
     136             : 
     137             :         pixel_text_size = NSMakeSize(pixel_row_height, pixel_row_height);
     138             :         
     139             :         pixel_title_size = NSMakeSize(pixel_row_height * 1.75f, pixel_row_height * 1.5f);
     140             :         
     141             :         unsigned i;
     142             :         
     143             :         rowRange = NSMakeRange(0,n_rows);
     144             : 
     145             :         rowText =   [[NSMutableArray alloc] initWithCapacity:n_rows];   // alloc retains
     146             :         rowKey =        [[NSMutableArray alloc] initWithCapacity:n_rows];   // alloc retains
     147             :         rowColor =      [[NSMutableArray alloc] initWithCapacity:n_rows];   // alloc retains
     148             :         
     149             :         for (i = 0; i < n_rows; i++)
     150             :         {
     151             :                 [rowText addObject:@""];
     152             :                 [rowKey addObject:@""];
     153             :                 [rowColor addObject:[OOColor greenColor]];
     154             :                 rowPosition[i].x = 0.0f;
     155             :                 rowPosition[i].y = size_in_pixels.height - (pixel_row_start + i * pixel_row_height);
     156             :                 rowAlignment[i] = GUI_ALIGN_LEFT;
     157             :         }
     158             :         
     159             :         title = [gui_title retain];
     160             :         
     161             :         textColor = [[OOColor yellowColor] retain];
     162             : 
     163             :         return self;
     164             : }
     165             : 
     166             : 
     167             : - (void) dealloc
     168             : {
     169             :         [backgroundSprite release];
     170             :         [foregroundSprite release];
     171             :         [backgroundColor release];
     172             :         [textColor release];
     173             :         [title release];
     174             :         [rowText release];
     175             :         [rowKey release];
     176             :         [rowColor release];
     177             :         [guiUserSettings release];
     178             : 
     179             :         [super dealloc];
     180             : }
     181             : 
     182             : 
     183             : - (void) resizeWithPixelSize:(NSSize)gui_size
     184             :                                          columns:(int)gui_cols
     185             :                                                 rows:(int)gui_rows
     186             :                                    rowHeight:(int)gui_row_height
     187             :                                         rowStart:(int)gui_row_start
     188             :                                            title:(NSString*) gui_title
     189             : {
     190             :         [self clear];
     191             :         //
     192             :         size_in_pixels  = gui_size;
     193             :         n_columns               = gui_cols;
     194             :         n_rows                  = gui_rows;
     195             :         pixel_row_center = size_in_pixels.width / 2;
     196             :         pixel_row_height = gui_row_height;
     197             :         pixel_row_start = gui_row_start;                // first position down the page...
     198             : 
     199             :         pixel_text_size = NSMakeSize(pixel_row_height, pixel_row_height);
     200             :         pixel_title_size = NSMakeSize(pixel_row_height * 1.75f, pixel_row_height * 1.5f);
     201             : 
     202             :         rowRange = NSMakeRange(0,n_rows);
     203             :         [self clear];
     204             :         //
     205             :         [self setTitle: gui_title];
     206             : }
     207             : 
     208             : 
     209             : - (void) resizeTo:(NSSize)gui_size
     210             :   characterHeight:(int)csize
     211             :                         title:(NSString*)gui_title
     212             : {
     213             :         [self clear];
     214             :         //
     215             :         size_in_pixels  = gui_size;
     216             :         n_columns               = gui_size.width / csize;
     217             :         n_rows                  = (int)gui_size.height / csize;
     218             : 
     219             :         [self setTitle: gui_title];
     220             :         
     221             :         pixel_row_center = gui_size.width / 2;
     222             :         pixel_row_height = csize;
     223             :         currentRow = n_rows - 1;                // first position down the page...
     224             : 
     225             :         if (title != nil)
     226             :                 pixel_row_start = 2.75f * csize + 0.5f * (gui_size.height - n_rows * csize);
     227             :         else
     228             :                 pixel_row_start = csize + 0.5f * (gui_size.height - n_rows * csize);
     229             : 
     230             :         [rowText removeAllObjects];
     231             :         [rowKey removeAllObjects];
     232             :         [rowColor removeAllObjects];
     233             : 
     234             :         unsigned i;
     235             :         for (i = 0; i < n_rows; i++)
     236             :         {
     237             :                 [rowText addObject:@""];
     238             :                 [rowKey addObject:@""];
     239             :                 [rowColor addObject:[OOColor greenColor]];
     240             :                 rowPosition[i].x = 0.0f;
     241             :                 rowPosition[i].y = size_in_pixels.height - (pixel_row_start + i * pixel_row_height);
     242             :                 rowAlignment[i] = GUI_ALIGN_LEFT;
     243             :         }
     244             : 
     245             :         pixel_text_size = NSMakeSize(csize, csize);
     246             :         pixel_title_size = NSMakeSize(csize * 1.75f, csize * 1.5f);
     247             :         
     248             :         OOLog(@"gui.reset", @"gui %@ reset to rows:%d columns:%d start:%d", self, n_rows, n_columns, pixel_row_start);
     249             : 
     250             :         rowRange = NSMakeRange(0,n_rows);
     251             :         [self clear];
     252             : }
     253             : 
     254             : 
     255             : - (NSSize)size
     256             : {
     257             :         return size_in_pixels;
     258             : }
     259             : 
     260             : 
     261             : - (unsigned)columns
     262             : {
     263             :         return n_columns;
     264             : }
     265             : 
     266             : 
     267             : - (unsigned)rows
     268             : {
     269             :         return n_rows;
     270             : }
     271             : 
     272             : 
     273             : - (unsigned)rowHeight
     274             : {
     275             :         return pixel_row_height;
     276             : }
     277             : 
     278             : 
     279             : - (int)rowStart
     280             : {
     281             :         return pixel_row_start;
     282             : }
     283             : 
     284             : 
     285             : - (NSString *)title
     286             : {
     287             :         return title;
     288             : }
     289             : 
     290             : 
     291             : - (void) setTitle:(NSString *)str
     292             : {
     293             :         if (str != title)
     294             :         {
     295             :                 [title release];
     296             :                 if ([str length] == 0)  str = nil;
     297             :                 title = [str copy];
     298             :         }
     299             : }
     300             : 
     301             : 
     302             : - (void) setDrawPosition:(Vector) vector
     303             : {
     304             :         drawPosition = vector;
     305             : }
     306             : 
     307             : 
     308             : - (Vector) drawPosition
     309             : {
     310             :         return drawPosition;
     311             : }
     312             : 
     313             : 
     314             : - (NSDictionary *) userSettings
     315             : {
     316             :         return guiUserSettings;
     317             : }
     318             : 
     319             : 
     320             : - (void) fadeOutFromTime:(OOTimeAbsolute) now_time overDuration:(OOTimeDelta) duration
     321             : {
     322             :         if (fade_alpha <= 0.0f) 
     323             :         {
     324             :                 return;
     325             :         }
     326             :         if (duration == 0.0)
     327             :                 fade_sign = -1000.0f;
     328             :         else
     329             :                 fade_sign = (float)(-fade_alpha / duration);
     330             : }
     331             : 
     332             : 
     333             : - (void) stopFadeOuts
     334             : {
     335             :         fade_sign = 0.0f;
     336             : }
     337             : 
     338             : 
     339             : - (GLfloat) alpha
     340             : {
     341             :         return fade_alpha;
     342             : }
     343             : 
     344             : 
     345             : - (void) setAlpha:(GLfloat) an_alpha
     346             : {
     347             :         fade_alpha = an_alpha * max_alpha;
     348             : }
     349             : 
     350             : 
     351             : - (void) setMaxAlpha:(GLfloat) an_alpha
     352             : {
     353             :         max_alpha = an_alpha;
     354             : }
     355             : 
     356             : 
     357             : - (void) setBackgroundColor:(OOColor*) color
     358             : {
     359             :         [backgroundColor release];
     360             :         backgroundColor = [color retain];
     361             : }
     362             : 
     363             : 
     364             : - (OOColor *) textColor
     365             : {
     366             :         return textColor;
     367             : }
     368             : 
     369             : 
     370             : // default text colour for rows
     371             : - (void) setTextColor:(OOColor*) color
     372             : {
     373             :         [textColor release];
     374             :         if (color == nil)  color = [[OOColor yellowColor] retain];
     375             :         textColor = [color retain];
     376             : }
     377             : 
     378             : 
     379             : - (OOColor *) textCommsColor
     380             : {
     381             :         return textCommsColor;
     382             : }
     383             : 
     384             : 
     385             : - (void) setTextCommsColor:(OOColor*) color
     386             : {
     387             :         [textCommsColor release];
     388             :         if (color == nil)  color = [[OOColor yellowColor] retain];
     389             :         textCommsColor = [color retain];
     390             : }
     391             : 
     392             : 
     393             : - (OOColor *) colorFromSetting:(NSString *)setting defaultValue:(OOColor *)def
     394             : {
     395             :         
     396             :         OOColor *col = nil;
     397             :         if (setting != nil) {
     398             :                 col = [OOColor colorWithDescription:[guiUserSettings objectForKey:setting]];
     399             :         }
     400             :         if (col == nil) {
     401             :                 if (def != nil) {
     402             :                         col = def;
     403             :                         // def = nil => use default_text_color
     404             :                 } else {
     405             :                         col = textColor;
     406             :                 }
     407             :         }
     408             :         return [[col copy] autorelease];
     409             : }
     410             : 
     411             : 
     412             : - (void) setGLColorFromSetting:(NSString *)setting defaultValue:(OOColor *)def alpha:(GLfloat)alpha
     413             : {
     414             :         GLfloat r,g,b,a;
     415             :         OOColor *col = [self colorFromSetting:setting defaultValue:def];
     416             :         [col getRed:&r green:&g blue:&b alpha:&a];
     417             : 
     418             :         OOGL(glColor4f(r, g, b, a*alpha));
     419             : }
     420             : 
     421             : 
     422             : - (void) setGuiColorSettingFromKey:(NSString *)key color:(OOColor *)col
     423             : {
     424             :         NSMutableDictionary *guiCopy = [guiUserSettings mutableCopy];
     425             :         if (col == nil)
     426             :         {
     427             :                 [guiCopy removeObjectForKey:key];
     428             :         } 
     429             :         else
     430             :         {
     431             :                 [guiCopy setObject:col forKey:key];
     432             :         }
     433             :         [guiUserSettings release];
     434             :         guiUserSettings = [guiCopy copy];
     435             :         [guiCopy release];
     436             : }
     437             : 
     438             : 
     439             : - (void) setCharacterSize:(NSSize) character_size
     440             : {
     441             :         pixel_text_size = character_size;
     442             : }
     443             : 
     444             : 
     445             : - (void)setShowAdvancedNavArray:(BOOL)inFlag
     446             : {
     447             :         showAdvancedNavArray = inFlag;
     448             : }
     449             : 
     450             : 
     451             : - (void) setColor:(OOColor *) color forRow:(OOGUIRow)row
     452             : {
     453             :         if (RowInRange(row, rowRange))
     454             :                 [rowColor replaceObjectAtIndex:row withObject:color];
     455             : }
     456             : 
     457             : 
     458             : - (id) objectForRow:(OOGUIRow)row
     459             : {
     460             :         if (RowInRange(row, rowRange))
     461             :                 return [rowText objectAtIndex:row];
     462             :         else
     463             :                 return NULL;
     464             : }
     465             : 
     466             : 
     467             : - (OOGUIRow) rowForKey:(NSString*)key
     468             : {
     469             :         for (unsigned i=0;i<[rowKey count];i++)
     470             :         {
     471             :                 if ([key isEqualToString:[rowKey objectAtIndex:i]])
     472             :                 {
     473             :                         return (OOGUIRow)i;
     474             :                 }
     475             :         }
     476             :         return -1;
     477             : }
     478             : 
     479             : 
     480             : - (NSString*) keyForRow:(OOGUIRow)row
     481             : {
     482             :         if (RowInRange(row, rowRange))
     483             :                 return [rowKey objectAtIndex:row];
     484             :         else
     485             :                 return NULL;
     486             : }
     487             : 
     488             : 
     489             : - (OOGUIRow) selectedRow
     490             : {
     491             :         if (RowInRange(selectedRow, selectableRange))
     492             :                 return selectedRow;
     493             :         else
     494             :                 return -1;
     495             : }
     496             : 
     497             : 
     498             : - (BOOL) setSelectedRow:(OOGUIRow)row
     499             : {
     500             :         if ((row == selectedRow)&&RowInRange(row, selectableRange))
     501             :                 return YES;
     502             :         if (RowInRange(row, selectableRange))
     503             :         {
     504             :                 if (![[rowKey objectAtIndex:row] isEqual:GUI_KEY_SKIP])
     505             :                 {
     506             :                         selectedRow = row;
     507             :                         return YES;
     508             :                 }
     509             :         }
     510             :         return NO;
     511             : }
     512             : 
     513             : 
     514             : - (BOOL) setNextRow:(int) direction
     515             : {
     516             :         OOGUIRow row = selectedRow + direction;
     517             :         while (RowInRange(row, selectableRange))
     518             :         {
     519             :                 if (![[rowKey objectAtIndex:row] isEqual:GUI_KEY_SKIP])
     520             :                 {
     521             :                         selectedRow = row;
     522             :                         return YES;
     523             :                 }
     524             :                 row += direction;
     525             :         }
     526             :         return NO;
     527             : }
     528             : 
     529             : 
     530             : - (BOOL) setFirstSelectableRow
     531             : {
     532             :         NSUInteger row = selectableRange.location;
     533             :         while (RowInRange(row, selectableRange))
     534             :         {
     535             :                 if (![[rowKey objectAtIndex:row] isEqual:GUI_KEY_SKIP])
     536             :                 {
     537             :                         selectedRow = row;
     538             :                         return YES;
     539             :                 }
     540             :                 row++;
     541             :         }
     542             :         selectedRow = -1;
     543             :         return NO;
     544             : }
     545             : 
     546             : 
     547             : - (BOOL) setLastSelectableRow
     548             : {
     549             :         NSUInteger row = selectableRange.location + selectableRange.length - 1;
     550             :         while (RowInRange(row, selectableRange))
     551             :         {
     552             :                 if (![[rowKey objectAtIndex:row] isEqual:GUI_KEY_SKIP])
     553             :                 {
     554             :                         selectedRow = row;
     555             :                         return YES;
     556             :                 }
     557             :                 row--;
     558             :         }
     559             :         selectedRow = -1;
     560             :         return NO;
     561             : }
     562             : 
     563             : 
     564             : - (void) setNoSelectedRow
     565             : {
     566             :         selectedRow = -1;
     567             : }
     568             : 
     569             : 
     570             : - (NSString *) selectedRowText
     571             : {
     572             :         if ([[rowText objectAtIndex:selectedRow] isKindOfClass:[NSString class]])
     573             :                 return (NSString *)[rowText objectAtIndex:selectedRow];
     574             :         if ([[rowText objectAtIndex:selectedRow] isKindOfClass:[NSArray class]])
     575             :                 return (NSString *)[[rowText objectAtIndex:selectedRow] objectAtIndex:0];
     576             :         return NULL;
     577             : }
     578             : 
     579             : 
     580             : - (NSString *) selectedRowKey
     581             : {
     582             :         if ((selectedRow < 0)||((unsigned)selectedRow > [rowKey count]))
     583             :                 return nil;
     584             :         else
     585             :                 return (NSString *)[rowKey objectAtIndex:selectedRow];
     586             : }
     587             : 
     588             : 
     589             : - (void) setShowTextCursor:(BOOL) yesno
     590             : {
     591             :         showTextCursor = yesno;
     592             : }
     593             : 
     594             : 
     595             : - (void) setCurrentRow:(OOGUIRow) value
     596             : {
     597             :         if ((value < 0)||((unsigned)value >= n_rows))
     598             :         {
     599             :                 showTextCursor = NO;
     600             :                 currentRow = -1;
     601             :         }
     602             :         else
     603             :         {
     604             :                 currentRow = value;
     605             :         }
     606             : }
     607             : 
     608             : 
     609             : - (NSRange) selectableRange
     610             : {
     611             :         return selectableRange;
     612             : }
     613             : 
     614             : 
     615             : - (void) setSelectableRange:(NSRange) range
     616             : {
     617             :         selectableRange = range;
     618             : }
     619             : 
     620             : 
     621             : - (void) setTabStops:(OOGUITabSettings)stops
     622             : {
     623             :         if (stops != NULL)  memmove(tabStops, stops, sizeof tabStops);
     624             : }
     625             : 
     626             : - (void) overrideTabs:(OOGUITabSettings)stops from:(NSString *)setting length:(NSUInteger)len
     627             : {
     628             :         NSArray *override = [guiUserSettings oo_arrayForKey:setting defaultValue:nil];
     629             :         NSUInteger i;
     630             :         if (stops != NULL && override != nil)
     631             :         {
     632             :                 if (len > GUI_MAX_COLUMNS)
     633             :                 {
     634             :                         len = GUI_MAX_COLUMNS;
     635             :                 }
     636             :                 for (i=0;i<len;i++) 
     637             :                 {
     638             :                         stops[i] = [override oo_unsignedIntegerAtIndex:i defaultValue:stops[i]];
     639             :                 }
     640             :         }
     641             : }
     642             : 
     643             : 
     644             : - (void) clear
     645             : {
     646             :         [self clearAndKeepBackground:NO];
     647             : }
     648             : 
     649             : 
     650             : - (void) clearAndKeepBackground:(BOOL)keepBackground
     651             : {
     652             :         unsigned i;
     653             :         [self setTitle: nil];
     654             :         for (i = 0; i < n_rows; i++)
     655             :         {
     656             :                 [self setText:@"" forRow:i align:GUI_ALIGN_LEFT];
     657             :                 [self setColor:textColor forRow:i];
     658             :                 //
     659             :                 [self setKey:GUI_KEY_SKIP forRow:i];
     660             :                 //
     661             :                 rowFadeTime[i] = 0.0f;
     662             :         }
     663             :         [self setShowTextCursor:NO];
     664             :         [self setSelectableRange:NSMakeRange(0,0)];
     665             :         if (!keepBackground) [self clearBackground];
     666             : }
     667             : 
     668             : 
     669             : - (void) setKey:(NSString *)str forRow:(OOGUIRow)row
     670             : {
     671             :         if (RowInRange(row, rowRange))
     672             :                 [rowKey replaceObjectAtIndex:row withObject:str];
     673             : }
     674             : 
     675             : 
     676             : - (void) setText:(NSString *)str forRow:(OOGUIRow)row
     677             : {
     678             :         if (RowInRange(row, rowRange))
     679             :         {
     680             :                 [rowText replaceObjectAtIndex:row withObject:str];
     681             :         }
     682             : }
     683             : 
     684             : 
     685             : - (void) setText:(NSString *)str forRow:(OOGUIRow)row align:(OOGUIAlignment)alignment
     686             : {
     687             :         if (str != nil && RowInRange(row, rowRange))
     688             :         {
     689             :                 [rowText replaceObjectAtIndex:row withObject:str];
     690             :                 rowAlignment[row] = alignment;
     691             :         }
     692             : }
     693             : 
     694             : 
     695             : - (OOGUIRow) addLongText:(NSString *)str
     696             :                    startingAtRow:(OOGUIRow)row
     697             :                                    align:(OOGUIAlignment)alignment
     698             : {
     699             : 
     700             :         if ([str rangeOfString:@"\n"].location != NSNotFound)
     701             :         {
     702             :                 NSArray         *lines = [str componentsSeparatedByString:@"\n"];
     703             :                 unsigned        i;
     704             :                 for (i = 0; i < [lines count]; i++)
     705             :                 {
     706             :                         row = [self addLongText:[lines oo_stringAtIndex:i] startingAtRow:row align:alignment];
     707             :                 }
     708             :                 return row;
     709             :         }
     710             :         
     711             :         NSSize chSize = pixel_text_size;
     712             :         NSSize strsize = OORectFromString(str, 0.0f, 0.0f, chSize).size;
     713             :         if (strsize.width < size_in_pixels.width)
     714             :         {
     715             :                 [self setText:str forRow:row align:alignment];
     716             :                 return row + 1;
     717             :         }
     718             :         else
     719             :         {
     720             :                 NSMutableArray  *words = ScanTokensFromString(str);
     721             :                 NSMutableString *string1 = [NSMutableString stringWithCapacity:256];
     722             :                 NSMutableString *string2 = [NSMutableString stringWithCapacity:256];
     723             :                 strsize.width = 0.0f;
     724             :                 while ((strsize.width < size_in_pixels.width)&&([words count] > 0))
     725             :                 {
     726             :                         [string1 appendString:(NSString *)[words objectAtIndex:0]];
     727             :                         [string1 appendString:@" "];
     728             :                         [words removeObjectAtIndex:0];
     729             :                         strsize = OORectFromString(string1, 0.0f, 0.0f, chSize).size;
     730             :                         if ([words count] > 0)
     731             :                                 strsize.width += OORectFromString((NSString *)[words objectAtIndex:0], 0.0f, 0.0f, chSize).size.width;
     732             :                 }
     733             :                 [string2 appendString:[words componentsJoinedByString:@" "]];
     734             :                 [self setText:string1           forRow:row                      align:alignment];
     735             :                 return  [self addLongText:string2   startingAtRow:row+1 align:alignment];
     736             :         }
     737             : }
     738             : 
     739             : 
     740             : - (NSString *) reflowTextForMFD:(NSString *)input
     741             : {
     742             :         NSMutableString *output = [[NSMutableString alloc] initWithCapacity:512];
     743             :         NSArray                  *lines = [input componentsSeparatedByString:@"\n"];
     744             :         NSSize                   chSize = pixel_text_size;
     745             :         NSUInteger        limit = chSize.width * 15;
     746             :         NSString                  *line = nil;
     747             :         foreach (line, lines)
     748             :         {
     749             :                 NSMutableArray  *words = ScanTokensFromString(line);
     750             :                 NSMutableString *accum = [NSMutableString stringWithCapacity:64];
     751             :                 if ([words count] > 0)
     752             :                 {
     753             :                         while ([words count] > 1)
     754             :                         {
     755             :                                 [accum appendString:[words oo_stringAtIndex:0]];
     756             :                                 [accum appendString:@" "];
     757             :                                 if (OORectFromString(accum, 0.0f, 0.0f,chSize).size.width + OORectFromString([words oo_stringAtIndex:1], 0.0f, 0.0f,chSize).size.width > limit)
     758             :                                 {
     759             :                                         // can't fit next word on this line
     760             :                                         [output appendString:[accum stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]];
     761             :                                         [output appendString:@"\n"];
     762             :                                         [accum setString:@""];
     763             :                                 }
     764             :                                 [words removeObjectAtIndex:0];
     765             :                         }
     766             :                         [output appendString:accum];
     767             :                         [output appendString:[words oo_stringAtIndex:0]];
     768             :                 }
     769             :                 [output appendString:@"\n"];
     770             :         }
     771             : 
     772             :         return [output autorelease];
     773             : }
     774             : 
     775             : 
     776             : - (void) leaveLastLine
     777             : {
     778             :         unsigned i;
     779             :         for (i=0; i < n_rows-1; i++)
     780             :         {
     781             :                 [rowText        replaceObjectAtIndex:i withObject:@""];
     782             :                 [rowColor       replaceObjectAtIndex:i withObject:textColor];
     783             :                 [rowKey         replaceObjectAtIndex:i withObject:@""];
     784             :                 rowAlignment[i] = GUI_ALIGN_LEFT;
     785             :                 rowFadeTime[i]  = 0.0f;
     786             :         }
     787             :         rowFadeTime[i]  = 0.4f; // fade the last line...
     788             : }
     789             : 
     790             : 
     791             : - (NSArray *) getLastLines      // text, colour, fade time - text, colour, fade time
     792             : {
     793             :         if (n_rows <1) return nil;
     794             :         
     795             :         // we have at least 1 row!
     796             :         
     797             :         unsigned                                i = n_rows-1;
     798             :         OORGBAComponents                col = [(OOColor *)[rowColor objectAtIndex:i] rgbaComponents];
     799             :         
     800             :         if (i>0)
     801             :         {
     802             :                 // we have at least 2 rows!
     803             :                 OORGBAComponents        col0 = [(OOColor *)[rowColor objectAtIndex:i-1] rgbaComponents];
     804             :                 return [NSArray arrayWithObjects:[rowText oo_stringAtIndex:i-1],
     805             :                                                                                 [NSString stringWithFormat:@"%.3g %.3g %.3g %.3g", col0.r, col0.g, col0.b, col0.a],
     806             :                                                                                 [NSNumber numberWithFloat:rowFadeTime[i-1]],
     807             :                                                                                 [rowText oo_stringAtIndex:i],
     808             :                                                                                 [NSString stringWithFormat:@"%.3g %.3g %.3g %.3g", col.r, col.g, col.b, col.a],
     809             :                                                                                 [NSNumber numberWithFloat:rowFadeTime[i]], nil];
     810             :         }
     811             :         else
     812             :         {
     813             :                 return [NSArray arrayWithObjects:[rowText oo_stringAtIndex:i],
     814             :                                                                                 [NSString stringWithFormat:@"%.3g %.3g %.3g %.3g", col.r, col.g, col.b, col.a],
     815             :                                                                                 [NSNumber numberWithFloat:rowFadeTime[i]], nil];
     816             :         }
     817             : }
     818             : 
     819             : 
     820             : - (void) printLongText:(NSString *)str
     821             :                                  align:(OOGUIAlignment) alignment
     822             :                                  color:(OOColor *)text_color
     823             :                           fadeTime:(float)text_fade
     824             :                                    key:(NSString *)text_key
     825             :                         addToArray:(NSMutableArray *)text_array
     826             : {
     827             :         // print a multi-line message
     828             :         //
     829             :         if ([str rangeOfString:@"\n"].location != NSNotFound)
     830             :         {
     831             :                 NSArray         *lines = [str componentsSeparatedByString:@"\n"];
     832             :                 unsigned        i;
     833             :                 for (i = 0; i < [lines count]; i++)
     834             :                         [self printLongText:[lines oo_stringAtIndex:i] align:alignment color:text_color fadeTime:text_fade key:text_key addToArray:text_array];
     835             :                 return;
     836             :         }
     837             :         
     838             :         OOGUIRow row = currentRow;
     839             :         if (row == (OOGUIRow)n_rows - 1)
     840             :                 [self scrollUp:1];
     841             :         NSSize chSize = pixel_text_size;
     842             :         NSSize strsize = OORectFromString(str, 0.0f, 0.0f, chSize).size;
     843             :         if (strsize.width < size_in_pixels.width)
     844             :         {
     845             :                 [self setText:str forRow:row align:alignment];
     846             :                 if (text_color)
     847             :                         [self setColor:text_color forRow:row];
     848             :                 if (text_key)
     849             :                         [self setKey:text_key forRow:row];
     850             :                 rowFadeTime[row] = text_fade;
     851             :                 if (currentRow < (OOGUIRow)n_rows - 1)
     852             :                         currentRow++;
     853             :                 if (text_array)
     854             :                         [text_array addObject:str];
     855             :         }
     856             :         else
     857             :         {
     858             :                 NSMutableArray  *words = ScanTokensFromString(str);
     859             :                 NSMutableString *string1 = [NSMutableString stringWithCapacity:256];
     860             :                 NSMutableString *string2 = [NSMutableString stringWithCapacity:256];    
     861             :                 strsize.width = 0.0f;
     862             :                 while ((strsize.width < size_in_pixels.width)&&([words count] > 0))
     863             :                 {
     864             :                         [string1 appendString:(NSString *)[words objectAtIndex:0]];
     865             :                         [string1 appendString:@" "];
     866             :                         [words removeObjectAtIndex:0];
     867             :                         strsize = OORectFromString(string1, 0.0f, 0.0f, chSize).size;
     868             :                         if ([words count] > 0)
     869             :                                 strsize.width += OORectFromString([words oo_stringAtIndex:0], 0.0f, 0.0f, chSize).size.width;
     870             :                 }
     871             : 
     872             :                 [self setText:string1           forRow:row                      align:alignment];
     873             : 
     874             :                 [string2 appendString:[words componentsJoinedByString:@" "]];
     875             :                 if (text_color)
     876             :                         [self setColor:text_color forRow:row];
     877             :                 if (text_key)
     878             :                         [self setKey:text_key forRow:row];
     879             :                 if (text_array)
     880             :                         [text_array addObject:string1];
     881             :                 rowFadeTime[row] = text_fade;
     882             :                 [self printLongText:string2 align:alignment color:text_color fadeTime:text_fade key:text_key addToArray:text_array];
     883             :         }
     884             : }
     885             : 
     886             : 
     887             : - (void) printLineNoScroll:(NSString *)str
     888             :                                          align:(OOGUIAlignment)alignment
     889             :                                           color:(OOColor *)text_color
     890             :                                   fadeTime:(float)text_fade
     891             :                                            key:(NSString *)text_key
     892             :                                 addToArray:(NSMutableArray *)text_array
     893             : {
     894             :         [self setText:str forRow:currentRow align:alignment];
     895             :         if (text_color)
     896             :                 [self setColor:text_color forRow:currentRow];
     897             :         if (text_key)
     898             :                 [self setKey:text_key forRow:currentRow];
     899             :         if (text_array)
     900             :                 [text_array addObject:str];
     901             :         rowFadeTime[currentRow] = text_fade;
     902             : }
     903             : 
     904             : 
     905             : - (void) setArray:(NSArray *)arr forRow:(OOGUIRow)row
     906             : {
     907             :         if (RowInRange(row, rowRange))
     908             :                 [rowText replaceObjectAtIndex:row withObject:arr];
     909             : }
     910             : 
     911             : 
     912             : - (void) insertItemsFromArray:(NSArray *)items
     913             :                                          withKeys:(NSArray *)item_keys
     914             :                                           intoRow:(OOGUIRow)row
     915             :                                                 color:(OOColor *)text_color
     916             : {
     917             :         if (!items)
     918             :                 return;
     919             :         if([items count] == 0)
     920             :                 return;
     921             :         
     922             :         NSUInteger n_items = [items count];
     923             :         if ((item_keys)&&([item_keys count] != n_items))
     924             :         {
     925             :                 // throw exception
     926             :                 [NSException raise:@"ArrayLengthMismatchException"
     927             :                                         format:@"The NSArray sent as 'item_keys' to insertItemsFromArray::: must contain the same number of objects as the NSArray 'items'"];
     928             :         }
     929             : 
     930             :         unsigned i;
     931             :         for (i = n_rows; i >= row + n_items ; i--)
     932             :         {
     933             :                 [self setKey:[self keyForRow:i - n_items] forRow:i];
     934             :                 id      old_row_info = [self objectForRow:i - n_items];
     935             :                 if ([old_row_info isKindOfClass:[NSArray class]])
     936             :                         [self setArray:old_row_info forRow:i];
     937             :                 if ([old_row_info isKindOfClass:[NSString class]])
     938             :                         [self setText:(NSString *)old_row_info forRow:i];
     939             :         }
     940             :         for (i = 0; i < n_items; i++)
     941             :         {
     942             :                 id new_row_info = [items objectAtIndex:i];
     943             :                 if (text_color)
     944             :                         [self setColor:text_color forRow: row + i];
     945             :                 else
     946             :                         [self setColor:textColor forRow: row + i];
     947             :                 if ([new_row_info isKindOfClass:[NSArray class]])
     948             :                         [self setArray:new_row_info forRow: row + i];
     949             :                 if ([new_row_info isKindOfClass:[NSString class]])
     950             :                         [self setText:(NSString *)new_row_info forRow: row + i];
     951             :                 if (item_keys)
     952             :                         [self setKey:[item_keys objectAtIndex:i] forRow: row + i];
     953             :                 else
     954             :                         [self setKey:@"" forRow: row + i];
     955             :         }
     956             : }
     957             : 
     958             : 
     959             : - (void) scrollUp:(int) how_much
     960             : {
     961             :         unsigned i;
     962             :         for (i = 0; i + how_much < n_rows; i++)
     963             :         {
     964             :                 [rowText        replaceObjectAtIndex:i withObject:[rowText objectAtIndex:       i + how_much]];
     965             :                 [rowColor       replaceObjectAtIndex:i withObject:[rowColor objectAtIndex:      i + how_much]];
     966             :                 [rowKey         replaceObjectAtIndex:i withObject:[rowKey objectAtIndex:        i + how_much]];
     967             :                 rowAlignment[i] = rowAlignment[i + how_much];
     968             :                 rowFadeTime[i]  = rowFadeTime[i + how_much];
     969             :         }
     970             :         for (; i < n_rows; i++)
     971             :         {
     972             :                 [rowText        replaceObjectAtIndex:i withObject:@""];
     973             :                 [rowColor       replaceObjectAtIndex:i withObject:textColor];
     974             :                 [rowKey         replaceObjectAtIndex:i withObject:@""];
     975             :                 rowAlignment[i] = GUI_ALIGN_LEFT;
     976             :                 rowFadeTime[i]  = 0.0f;
     977             :         }
     978             : }
     979             : 
     980             : 
     981             : - (void) clearBackground
     982             : {
     983             :         [self setBackgroundTextureDescriptor:nil];
     984             :         [self setForegroundTextureDescriptor:nil];
     985             : }
     986             : 
     987             : 
     988           0 : static OOTexture *TextureForGUITexture(NSDictionary *descriptor)
     989             : {
     990             :         /*
     991             :                 GUI textures like backgrounds, foregrounds etc. are not processed in any way after loading. However, they are
     992             :                 subject to tone nmapping and gamma correction at the end of the render pass. So we need to declare them as
     993             :                 SRGBA textures here so that OpenGL will automatically convert them to linear space upon loading and the
     994             :                 subsequent tone mapping and gamma correction shader operations will not result in heavy distortion of their
     995             :                 colors.
     996             :                 
     997             :                 Also, remember that if no shaders are in use (as in lower detail levels), then we don't need to declare anything.
     998             :         */
     999             :         uint32_t srgbaOption = 0UL;
    1000             :         if ([UNIVERSE useShaders])  srgbaOption = kOOTextureSRGBA;
    1001             :         return [OOTexture textureWithName:[descriptor oo_stringForKey:@"name"]
    1002             :                                                          inFolder:@"Images"
    1003             :                                                           options:kOOTextureDefaultOptions | kOOTextureNoShrink | srgbaOption
    1004             :                                                    anisotropy:kOOTextureDefaultAnisotropy
    1005             :                                                           lodBias:kOOTextureDefaultLODBias];
    1006             : }
    1007             : 
    1008             : 
    1009             : /*
    1010             :         Load a texture sprite given a descriptor. The caller owns a reference to
    1011             :         the result.
    1012             : */
    1013           0 : static OOTextureSprite *NewTextureSpriteWithDescriptor(NSDictionary *descriptor)
    1014             : {
    1015             :         OOTexture               *texture = nil;
    1016             :         NSSize                  size;
    1017             :         
    1018             :         texture = TextureForGUITexture(descriptor);
    1019             :         if (texture == nil)  return nil;
    1020             :         
    1021             :         double specifiedWidth = [descriptor oo_doubleForKey:@"width" defaultValue:-INFINITY];
    1022             :         double specifiedHeight = [descriptor oo_doubleForKey:@"height" defaultValue:-INFINITY];
    1023             :         BOOL haveWidth = isfinite(specifiedWidth);
    1024             :         BOOL haveHeight = isfinite(specifiedHeight);
    1025             :         
    1026             :         if (haveWidth && haveHeight)
    1027             :         {
    1028             :                 // Both specified, use directly without calling -originalDimensions (which may block).
    1029             :                 size.width = specifiedWidth;
    1030             :                 size.height = specifiedHeight;
    1031             :         }
    1032             :         else
    1033             :         {
    1034             :                 NSSize originalDimensions = [texture originalDimensions];
    1035             :                 
    1036             :                 if (haveWidth)
    1037             :                 {
    1038             :                         // Width specified, but not height; preserve aspect ratio.
    1039             :                         CGFloat ratio = originalDimensions.height / originalDimensions.width;
    1040             :                         size.width = specifiedWidth;
    1041             :                         size.height = ratio * size.width;
    1042             :                 }
    1043             :                 else if (haveHeight)
    1044             :                 {
    1045             :                         // Height specified, but not width; preserve aspect ratio.
    1046             :                         CGFloat ratio = originalDimensions.width / originalDimensions.height;
    1047             :                         size.height = specifiedHeight;
    1048             :                         size.width = ratio * size.height;
    1049             :                 }
    1050             :                 else
    1051             :                 {
    1052             :                         // Neither specified; use backwards-compatible behaviour.
    1053             :                         size = originalDimensions;
    1054             :                 }
    1055             :         }
    1056             :         
    1057             :         return [[OOTextureSprite alloc] initWithTexture:texture size:size];
    1058             : }
    1059             : 
    1060             : 
    1061             : - (void) setBackgroundTextureSpecial:(OOGUIBackgroundSpecial)spec withBackground:(BOOL)withBackground
    1062             : {
    1063             :         if (withBackground) 
    1064             :         {
    1065             :                 NSDictionary *bgDescriptor = nil;
    1066             :                 OOGalaxyID galaxy_number = [PLAYER galaxyNumber];
    1067             : 
    1068             :                 switch (spec) 
    1069             :                 {
    1070             :                 case GUI_BACKGROUND_SPECIAL_CUSTOM:
    1071             :                 case GUI_BACKGROUND_SPECIAL_CUSTOM_ANA_SHORTEST:
    1072             :                 case GUI_BACKGROUND_SPECIAL_CUSTOM_ANA_QUICKEST:
    1073             :                         bgDescriptor = [UNIVERSE screenTextureDescriptorForKey:@"custom_chart_mission"];
    1074             :                         if (bgDescriptor == nil) 
    1075             :                         {
    1076             :                                 bgDescriptor = [UNIVERSE screenTextureDescriptorForKey:@"short_range_chart_mission"];
    1077             :                                 if (bgDescriptor == nil) 
    1078             :                                 {
    1079             :                                         bgDescriptor = [UNIVERSE screenTextureDescriptorForKey:@"short_range_chart"];
    1080             :                                 }
    1081             :                         }
    1082             :                         break;
    1083             :                 case GUI_BACKGROUND_SPECIAL_SHORT:
    1084             :                 case GUI_BACKGROUND_SPECIAL_SHORT_ANA_SHORTEST:
    1085             :                 case GUI_BACKGROUND_SPECIAL_SHORT_ANA_QUICKEST:
    1086             :                         bgDescriptor = [UNIVERSE screenTextureDescriptorForKey:@"short_range_chart_mission"];
    1087             :                         if (bgDescriptor == nil) 
    1088             :                         {
    1089             :                                 bgDescriptor = [UNIVERSE screenTextureDescriptorForKey:@"short_range_chart"];
    1090             :                         }
    1091             :                         break;
    1092             :                 case GUI_BACKGROUND_SPECIAL_LONG:
    1093             :                 case GUI_BACKGROUND_SPECIAL_LONG_ANA_SHORTEST:
    1094             :                 case GUI_BACKGROUND_SPECIAL_LONG_ANA_QUICKEST:
    1095             :                         bgDescriptor = [UNIVERSE screenTextureDescriptorForKey:[NSString stringWithFormat:@"long_range_chart%d_mission", galaxy_number+1]];
    1096             :                         if (bgDescriptor == nil) 
    1097             :                         {
    1098             :                                 bgDescriptor = [UNIVERSE screenTextureDescriptorForKey:@"long_range_chart_mission"];
    1099             :                                 if (bgDescriptor == nil) 
    1100             :                                 {
    1101             :                                         bgDescriptor = [UNIVERSE screenTextureDescriptorForKey:[NSString stringWithFormat:@"long_range_chart%d", galaxy_number+1]];
    1102             :                                         if (bgDescriptor == nil) 
    1103             :                                         {
    1104             :                                                 bgDescriptor = [UNIVERSE screenTextureDescriptorForKey:@"long_range_chart"];
    1105             :                                                 
    1106             :                                         }
    1107             :                                 }
    1108             :                         }
    1109             :                         break;
    1110             :                 case GUI_BACKGROUND_SPECIAL_NONE:
    1111             :                         break;
    1112             :                 }
    1113             :                 if (bgDescriptor != nil)
    1114             :                 {
    1115             :                         [self setBackgroundTextureDescriptor:bgDescriptor];
    1116             :                 }
    1117             :         }
    1118             :         backgroundSpecial = spec;
    1119             :         [self refreshStarChart];
    1120             : }
    1121             : 
    1122             : 
    1123             : - (BOOL) setBackgroundTextureDescriptor:(NSDictionary *)descriptor
    1124             : {
    1125             :         [backgroundSprite autorelease];
    1126             :         backgroundSpecial = GUI_BACKGROUND_SPECIAL_NONE; // reset
    1127             :         backgroundSprite = NewTextureSpriteWithDescriptor(descriptor);
    1128             :         return backgroundSprite != nil;
    1129             : }
    1130             : 
    1131             : 
    1132             : - (BOOL) setForegroundTextureDescriptor:(NSDictionary *)descriptor
    1133             : {
    1134             :         [foregroundSprite autorelease];
    1135             :         foregroundSprite = NewTextureSpriteWithDescriptor(descriptor);
    1136             :         return foregroundSprite != nil;
    1137             : }
    1138             : 
    1139             : 
    1140             : - (BOOL) setBackgroundTextureKey:(NSString *)key
    1141             : {
    1142             :         return [self setBackgroundTextureDescriptor:[UNIVERSE screenTextureDescriptorForKey:key]];
    1143             : }
    1144             : 
    1145             : 
    1146             : - (BOOL) setForegroundTextureKey:(NSString *)key
    1147             : {
    1148             :         return [self setForegroundTextureDescriptor:[UNIVERSE screenTextureDescriptorForKey:key]];
    1149             : }
    1150             : 
    1151             : 
    1152             : - (BOOL) preloadGUITexture:(NSDictionary *)descriptor
    1153             : {
    1154             :         return TextureForGUITexture(descriptor) != nil;
    1155             : }
    1156             : 
    1157             : 
    1158             : - (NSDictionary *) textureDescriptorFromJSValue:(jsval)value
    1159             :                                                                           inContext:(JSContext *)context
    1160             :                                                           callerDescription:(NSString *)callerDescription
    1161             : {
    1162             :         OOJS_PROFILE_ENTER
    1163             :         
    1164             :         NSDictionary    *result = nil;
    1165             :         
    1166             :         if (JSVAL_IS_OBJECT(value))
    1167             :         {
    1168             :                 // Null may be used to indicate no texture.
    1169             :                 if (JSVAL_IS_NULL(value))  return [NSDictionary dictionary];
    1170             :                 
    1171             :                 JSObject *objValue = JSVAL_TO_OBJECT(value);
    1172             :                 
    1173             :                 if (OOJSGetClass(context, objValue) != [[OOJavaScriptEngine sharedEngine] stringClass])
    1174             :                 {
    1175             :                         result = OOJSDictionaryFromJSObject(context, objValue);
    1176             :                 }
    1177             :         }
    1178             :         
    1179             :         if (result == nil)
    1180             :         {
    1181             :                 NSString *name = OOStringFromJSValue(context, value);
    1182             : 
    1183             :                 if (name != nil)
    1184             :                 {
    1185             :                         result = [NSDictionary dictionaryWithObject:name forKey:@"name"];
    1186             :                         if ([name length] == 0)  return result; // Explicit empty string may be used to indicate no texture.
    1187             :                 }
    1188             :         }
    1189             :         
    1190             :         // Start loading the texture, and return nil if it doesn't exist.
    1191             :         if (result != nil && ![self preloadGUITexture:result])
    1192             :         {
    1193             :                 OOJSReportWarning(context, @"%@: texture \"%@\" could not be found.", callerDescription, [result oo_stringForKey:@"name"]);
    1194             :                 result = nil;
    1195             :         }
    1196             :         
    1197             :         return result;
    1198             :         
    1199             :         OOJS_PROFILE_EXIT
    1200             : }
    1201             : 
    1202             : 
    1203             : - (void) setStatusPage:(NSInteger)pageNum
    1204             : {
    1205             :         if (pageNum == 0 || (pageNum < 0 && ((NSUInteger)-pageNum) >= statusPage))
    1206             :         { 
    1207             :                 statusPage = 1;
    1208             :         }
    1209             :         else 
    1210             :         {
    1211             :                 statusPage += pageNum;
    1212             :         }
    1213             : }
    1214             : 
    1215             : 
    1216             : - (NSUInteger) statusPage
    1217             : {
    1218             :         return statusPage;
    1219             : }
    1220             : 
    1221             : 
    1222           1 : - (void) drawEquipmentList:(NSArray *)eqptList z:(GLfloat)z
    1223             : {
    1224             :         if ([eqptList count] == 0) return;
    1225             :         
    1226             :         OOGUIRow                firstRow = STATUS_EQUIPMENT_FIRST_ROW;
    1227             :         NSUInteger              maxRows = STATUS_EQUIPMENT_MAX_ROWS;
    1228             :         if ([[PLAYER hud] allowBigGui])
    1229             :         {
    1230             :                 maxRows += STATUS_EQUIPMENT_BIGGUI_EXTRA_ROWS;
    1231             :         }
    1232             :         NSUInteger              itemsPerColumn = maxRows;
    1233             : 
    1234             : 
    1235             :         NSInteger               firstY = 40;    // firstRow =10 :-> 40  - firstRow=11 -> 24 etc...
    1236             :         NSUInteger              eqptCount = [eqptList count];
    1237             :         NSUInteger              pageCount = 1;
    1238             :         NSUInteger              i;
    1239             :         NSInteger               start;
    1240             :         NSArray                 *info = nil;
    1241             :         NSString                *name = nil;
    1242             :         BOOL                    damaged;
    1243             :         
    1244             :         // Paging calculations. Assuming 10 lines we get - one page:20 items per page (ipp)
    1245             :         // two pages: 18 ipp - three+ pages:  1st & last 18pp,  middle pages 16ipp
    1246             :         
    1247             :         i = itemsPerColumn * 2 + 2;
    1248             :         if (eqptCount > i) // don't fit in one page?
    1249             :         {
    1250             :                 [[UNIVERSE gameController] setMouseInteractionModeForUIWithMouseInteraction:YES];
    1251             :                  
    1252             :                 i = itemsPerColumn * 4; // total items in the first and last pages
    1253             :                 itemsPerColumn--; // for all the middle pages.
    1254             :                 if (eqptCount <= i) // two pages
    1255             :                 {
    1256             :                         pageCount++;
    1257             :                         if (statusPage == 1)
    1258             :                         {
    1259             :                                 start = 0;
    1260             :                         }
    1261             :                         else
    1262             :                         {
    1263             :                                 statusPage = 2;
    1264             :                                 start = i/statusPage; // for the for loop
    1265             :                         }
    1266             :                 }
    1267             :                 else // three or more
    1268             :                 {
    1269             :                         pageCount = ceil((float)(eqptCount-i)/(itemsPerColumn*2)) + 2;
    1270             :                         statusPage = (NSInteger)OOClampInteger(statusPage, 1, pageCount);
    1271             :                         start = (statusPage == 1) ? 0 : (statusPage-1) * itemsPerColumn * 2 + 2;
    1272             :                 }
    1273             :         }
    1274             :         else
    1275             :         {
    1276             :                 statusPage = pageCount; // one page
    1277             :                 start = 0;
    1278             :                 // if we have mouse interaction active, it means that we had more than one
    1279             :                 // pages earlier, but only one now, as e.g. in the case of a hud that wss
    1280             :                 // subsequently hidden, resulting in the equip list fitting in one page,
    1281             :                 // so we need to deactivate it
    1282             :                 if (OOMouseInteractionModeIsUIScreen([[UNIVERSE gameController] mouseInteractionMode]))
    1283             :                 {
    1284             :                         // clear the gui-more and gui-back key rows first
    1285             :                         [self setText:@"" forRow:firstRow];
    1286             :                         [self setKey:GUI_KEY_SKIP forRow:firstRow];
    1287             :                         [self setText:@"" forRow:firstRow + STATUS_EQUIPMENT_MAX_ROWS];
    1288             :                         [self setKey:GUI_KEY_SKIP forRow:firstRow + STATUS_EQUIPMENT_MAX_ROWS];
    1289             :                         [self setSelectableRange:NSMakeRange(0,0)];
    1290             :                         
    1291             :                         [[UNIVERSE gameController] setMouseInteractionModeForUIWithMouseInteraction:NO];
    1292             :                 }
    1293             :         }
    1294             :         
    1295             :         if (statusPage > 1)
    1296             :         {
    1297             :                 [self setColor:[self colorFromSetting:kGuiStatusEquipmentScrollColor defaultValue:[OOColor greenColor]] forRow:firstRow];
    1298             :                 [self setArray:[NSArray arrayWithObjects:DESC(@"gui-back"),  @"", @" <-- ",nil] forRow:firstRow];
    1299             :                 [self setKey:GUI_KEY_OK forRow:firstRow];
    1300             :                 firstY -= 16; // start 1 row down!
    1301             :                 if (statusPage == pageCount)
    1302             :                 {
    1303             :                         [self setSelectableRange:NSMakeRange(firstRow, 1)];
    1304             :                         [self setSelectedRow:firstRow];
    1305             :                 }
    1306             :         }
    1307             :         if (statusPage < pageCount)
    1308             :         {
    1309             :                 [self setColor:[self colorFromSetting:kGuiStatusEquipmentScrollColor defaultValue:[OOColor greenColor]] forRow:firstRow + maxRows];
    1310             :                 [self setArray:[NSArray arrayWithObjects:DESC(@"gui-more"),  @"", @" --> ",nil] forRow:firstRow + maxRows];
    1311             :                 [self setKey:GUI_KEY_OK forRow:firstRow + maxRows];
    1312             :                 if (statusPage == 1)
    1313             :                 {
    1314             :                         [self setSelectableRange:NSMakeRange(firstRow + maxRows, 1)];
    1315             :                         [self setSelectedRow:firstRow + maxRows];
    1316             :                 }
    1317             :         }
    1318             :         if (statusPage > 1 && statusPage < pageCount)
    1319             :         {
    1320             :                 [self setSelectableRange:NSMakeRange(firstRow, MIN(firstRow + maxRows, GUI_DEFAULT_ROWS - firstRow))];
    1321             :                 // default selected row to 'More -->' if we are looking at one of the middle pages
    1322             :                 if ([self selectedRow] == -1)  [self setSelectedRow:firstRow + maxRows];
    1323             :         }
    1324             : 
    1325             :         if (statusPage == 1 || statusPage == pageCount) itemsPerColumn++;
    1326             :         eqptCount = (NSInteger)OOClampInteger(eqptCount, 1, start + itemsPerColumn * 2);
    1327             :         for (i = start; i < eqptCount; i++)
    1328             :         {
    1329             :                 info = [eqptList oo_arrayAtIndex:i];
    1330             :                 name = [info oo_stringAtIndex:0];
    1331             :                 if([name length] > 42)  name = [[name substringToIndex:40] stringByAppendingString:@"..."];
    1332             :                 
    1333             :                 damaged = ![info oo_boolAtIndex:1];
    1334             :                 if (damaged) 
    1335             :                 {
    1336             :                         // Damaged items show up orange.
    1337             :                         [self setGLColorFromSetting:@"status_equipment_damaged_color" defaultValue:[OOColor orangeColor] alpha:1.0];
    1338             :                 } 
    1339             :                 else /// add color selection here
    1340             :                 {
    1341             :                         OOColor                         *dispCol = [info oo_objectAtIndex:2];
    1342             :                         // Normal items in default colour
    1343             :                         [self setGLColorFromSetting:@"status_equipment_ok_color" defaultValue:dispCol alpha:1.0];
    1344             :                 }
    1345             :                 
    1346             :                 if (i - start < itemsPerColumn)
    1347             :                 {
    1348             :                         OODrawString(name, -220, firstY - 16 * (NSInteger)(i - start), z, NSMakeSize(15, 15));
    1349             :                 }
    1350             :                 else
    1351             :                 {
    1352             :                         OODrawString(name, 50, firstY - 16 * (NSInteger)(i - itemsPerColumn - start), z, NSMakeSize(15, 15));
    1353             :                 }
    1354             :         }
    1355             : }
    1356             : 
    1357             : 
    1358             : - (void) drawGUIBackground
    1359             : {
    1360             :         GLfloat x = drawPosition.x;
    1361             :         GLfloat y = drawPosition.y;
    1362             :         GLfloat z = [[UNIVERSE gameView] display_z];
    1363             : 
    1364             :         if (backgroundSprite!=nil)
    1365             :         {
    1366             :                 [backgroundSprite blitBackgroundCentredToX:x Y:y Z:z alpha:1.0f];
    1367             :         }
    1368             :         
    1369             : }
    1370             : 
    1371             : 
    1372             : - (void) refreshStarChart
    1373             : {
    1374             :         _refreshStarChart = YES;
    1375             : }
    1376             : 
    1377             : 
    1378             : - (int) drawGUI:(GLfloat) alpha drawCursor:(BOOL) drawCursor
    1379             : {
    1380             :         GLfloat x = drawPosition.x;
    1381             :         GLfloat y = drawPosition.y;
    1382             :         GLfloat z = [[UNIVERSE gameView] display_z];
    1383             :         
    1384             :         if (alpha > 0.05f)
    1385             :         {
    1386             :                 PlayerEntity* player = PLAYER;
    1387             :                 
    1388             :                 [self drawGLDisplay:x - 0.5f * size_in_pixels.width :y - 0.5f * size_in_pixels.height :z :alpha];
    1389             :                 
    1390             :                 if (self == [UNIVERSE gui])
    1391             :                 {
    1392             :                         if ([player guiScreen] == GUI_SCREEN_SHORT_RANGE_CHART || [player guiScreen] == GUI_SCREEN_LONG_RANGE_CHART || 
    1393             :                                 backgroundSpecial == GUI_BACKGROUND_SPECIAL_SHORT ||
    1394             :                                 backgroundSpecial == GUI_BACKGROUND_SPECIAL_SHORT_ANA_QUICKEST ||
    1395             :                                 backgroundSpecial == GUI_BACKGROUND_SPECIAL_SHORT_ANA_SHORTEST ||
    1396             :                                 backgroundSpecial == GUI_BACKGROUND_SPECIAL_CUSTOM ||
    1397             :                                 backgroundSpecial == GUI_BACKGROUND_SPECIAL_CUSTOM_ANA_QUICKEST ||
    1398             :                                 backgroundSpecial == GUI_BACKGROUND_SPECIAL_CUSTOM_ANA_SHORTEST)
    1399             :                         {
    1400             :                                 [self drawStarChart:x - 0.5f * size_in_pixels.width :y - 0.5f * size_in_pixels.height :z :alpha :NO];
    1401             :                         }
    1402             :                         if (backgroundSpecial == GUI_BACKGROUND_SPECIAL_LONG || 
    1403             :                                         backgroundSpecial == GUI_BACKGROUND_SPECIAL_LONG_ANA_QUICKEST ||
    1404             :                                         backgroundSpecial == GUI_BACKGROUND_SPECIAL_LONG_ANA_SHORTEST)
    1405             :                         {
    1406             :                                 [self drawStarChart:x - 0.5f * size_in_pixels.width :y - 0.5f * size_in_pixels.height :z :alpha :YES];
    1407             :                         }
    1408             :                         if ([player guiScreen] == GUI_SCREEN_STATUS)
    1409             :                         {
    1410             :                                 [self drawEquipmentList:[player equipmentList] z:z];
    1411             :                         }
    1412             :                         if ([player guiScreen] == GUI_SCREEN_STICKPROFILE)
    1413             :                         {
    1414             :                                 [player stickProfileGraphAxisProfile: alpha screenAt: make_vector(x,y,z) screenSize: size_in_pixels];
    1415             :                         }
    1416             :                 }
    1417             :                 
    1418             :                 if (fade_sign)
    1419             :                 {
    1420             :                         fade_alpha += (float)(fade_sign * [UNIVERSE getTimeDelta]);
    1421             :                         if (fade_alpha < 0.05f)      // done fading out
    1422             :                         {
    1423             :                                 fade_alpha = 0.0f;
    1424             :                                 fade_sign = 0.0f;
    1425             :                         }
    1426             :                         if (fade_alpha >= max_alpha) // done fading in
    1427             :                         {
    1428             :                                 fade_alpha = max_alpha;
    1429             :                                 fade_sign = 0.0f;
    1430             :                         }
    1431             :                 }
    1432             :         }
    1433             :         
    1434             :         int cursor_row = 0;
    1435             : 
    1436             :         if (drawCursor)
    1437             :         {
    1438             :                 NSPoint vjpos = [[UNIVERSE gameView] virtualJoystickPosition];
    1439             :                 double cursor_x = size_in_pixels.width * vjpos.x;
    1440             :                 if (cursor_x < -size_in_pixels.width * 0.5)  cursor_x = -size_in_pixels.width * 0.5f;
    1441             :                 if (cursor_x > size_in_pixels.width * 0.5)   cursor_x = size_in_pixels.width * 0.5f;
    1442             :                 double cursor_y = -size_in_pixels.height * vjpos.y;
    1443             :                 if (cursor_y < -size_in_pixels.height * 0.5)  cursor_y = -size_in_pixels.height * 0.5f;
    1444             :                 if (cursor_y > size_in_pixels.height * 0.5)   cursor_y = size_in_pixels.height * 0.5f;
    1445             :                 
    1446             :                 cursor_row = 1 + (float)floor((0.5f * size_in_pixels.height - pixel_row_start - cursor_y) / pixel_row_height);
    1447             :                 
    1448             :                 GLfloat h1 = 3.0f;
    1449             :                 GLfloat h3 = 9.0f;
    1450             :                 OOGL(glColor4f(0.6f, 0.6f, 1.0f, 1.0f)); // original value of (0.2f, 0.2f, 1.0f, 0.5f) too dark - Nikos 20130616
    1451             :                 OOGL(GLScaledLineWidth(2.0f));
    1452             :                 
    1453             :                 cursor_x += x;
    1454             :                 cursor_y += y;
    1455             :                 [[UNIVERSE gameView] setVirtualJoystick:cursor_x/size_in_pixels.width :-cursor_y/size_in_pixels.height];
    1456             : 
    1457             :                 OOGLBEGIN(GL_LINES);
    1458             :                         glVertex3f((float)cursor_x - h1, (float)cursor_y, z);   glVertex3f((float)cursor_x - h3, (float)cursor_y, z);
    1459             :                         glVertex3f((float)cursor_x + h1, (float)cursor_y, z);   glVertex3f((float)cursor_x + h3, (float)cursor_y, z);
    1460             :                         glVertex3f((float)cursor_x, (float)cursor_y - h1, z);   glVertex3f((float)cursor_x, (float)cursor_y - h3, z);
    1461             :                         glVertex3f((float)cursor_x, (float)cursor_y + h1, z);   glVertex3f((float)cursor_x, (float)cursor_y + h3, z);
    1462             :                 OOGLEND();
    1463             :                 OOGL(GLScaledLineWidth(1.0f));
    1464             :                 
    1465             :         }
    1466             :         
    1467             :         return cursor_row;
    1468             : }
    1469             : 
    1470             : 
    1471           0 : - (void) drawGLDisplay:(GLfloat)x :(GLfloat)y :(GLfloat)z :(GLfloat) alpha
    1472             : {
    1473             :         NSSize          strsize;
    1474             :         unsigned        i;
    1475             :         OOTimeDelta     delta_t = [UNIVERSE getTimeDelta];
    1476             :         NSSize          characterSize = pixel_text_size;
    1477             :         NSSize          titleCharacterSize = pixel_title_size;
    1478             :         float           backgroundAlpha = self == [UNIVERSE messageGUI] && ![UNIVERSE permanentMessageLog] ? 0.0f : alpha;
    1479             :         float           row_alpha[n_rows];
    1480             :         
    1481             :         // calculate fade out time and alpha for each row. Do it before
    1482             :         // applying a potential background because we need the maximum alpha
    1483             :         // of all rows to be the alpha applied to the background color
    1484             :         for (i = 0; i < n_rows; i++)
    1485             :         {
    1486             :                 row_alpha[i] = alpha;
    1487             :                 
    1488             :                 if(![UNIVERSE autoMessageLogBg] && [PLAYER guiScreen] == GUI_SCREEN_MAIN)  backgroundAlpha = alpha;
    1489             :                 
    1490             :                 if (rowFadeTime[i] > 0.0f && ![UNIVERSE permanentMessageLog])
    1491             :                 {
    1492             :                         rowFadeTime[i] -= (float)delta_t;
    1493             :                         if (rowFadeTime[i] <= 0.0f)
    1494             :                         {
    1495             :                                 [rowText replaceObjectAtIndex:i withObject:@""];
    1496             :                                 rowFadeTime[i] = 0.0f;
    1497             :                                 continue;
    1498             :                         }
    1499             :                         if ((rowFadeTime[i] > 0.0f)&&(rowFadeTime[i] < 1.0))
    1500             :                         {
    1501             :                                 row_alpha[i] *= rowFadeTime[i];
    1502             :                                 if (backgroundAlpha < row_alpha[i])  backgroundAlpha = row_alpha[i];
    1503             :                         }
    1504             :                         else
    1505             :                         {
    1506             :                                 backgroundAlpha = alpha;
    1507             :                         }
    1508             :                 }
    1509             :         }
    1510             :         
    1511             :         // do backdrop
    1512             :         // don't draw it if docked, unless message_gui is permanent
    1513             :         // don't draw it on the intro screens
    1514             :         if (backgroundColor)
    1515             :         {
    1516             :                 int playerStatus = [PLAYER status];
    1517             :                 if (playerStatus != STATUS_START_GAME && playerStatus != STATUS_DEAD)
    1518             :                 {
    1519             :                         OOGL(glColor4f([backgroundColor redComponent], [backgroundColor greenComponent], [backgroundColor blueComponent], backgroundAlpha * [backgroundColor alphaComponent]));
    1520             :                         OOGLBEGIN(GL_QUADS);
    1521             :                                 glVertex3f(x + 0.0f,                                    y + 0.0f,                                       z);
    1522             :                                 glVertex3f(x + size_in_pixels.width,    y + 0.0f,                                       z);
    1523             :                                 glVertex3f(x + size_in_pixels.width,    y + size_in_pixels.height,      z);
    1524             :                                 glVertex3f(x + 0.0f,                                    y + size_in_pixels.height,      z);
    1525             :                         OOGLEND();
    1526             :                 }
    1527             :         }
    1528             :         
    1529             :         // show the 'foreground', aka overlay!
    1530             :         
    1531             :         if (foregroundSprite != nil)
    1532             :         {
    1533             :                 [foregroundSprite blitCentredToX:x + 0.5f * size_in_pixels.width Y:y + 0.5f * size_in_pixels.height Z:z alpha:alpha];
    1534             :         }
    1535             :         
    1536             :         if (!RowInRange(selectedRow, selectableRange))
    1537             :                 selectedRow = -1;   // out of Range;
    1538             :         
    1539             :         ////
    1540             :         // drawing operations here
    1541             :         
    1542             :         if (title != nil)
    1543             :         {
    1544             :                 //
    1545             :                 // draw the title
    1546             :                 //
    1547             :                 strsize = OORectFromString(title, 0.0f, 0.0f, titleCharacterSize).size;
    1548             :                 [self setGLColorFromSetting:kGuiScreenTitleColor defaultValue:[OOColor redColor] alpha:alpha];
    1549             : 
    1550             :                 OODrawString(title, x + pixel_row_center - strsize.width/2.0, y + size_in_pixels.height - pixel_title_size.height, z, titleCharacterSize);
    1551             :                 
    1552             :                 // draw a horizontal divider
    1553             :                 //
    1554             :                 [self setGLColorFromSetting:kGuiScreenDividerColor defaultValue:[OOColor colorWithWhite:0.75 alpha:1.0] alpha:alpha];
    1555             : 
    1556             :                 OOGLBEGIN(GL_QUADS);
    1557             :                         glVertex3f(x + 0,                                       y + size_in_pixels.height - pixel_title_size.height + 4,        z);
    1558             :                         glVertex3f(x + size_in_pixels.width,    y + size_in_pixels.height - pixel_title_size.height + 4,        z);
    1559             :                         glVertex3f(x + size_in_pixels.width,    y + size_in_pixels.height - pixel_title_size.height + 2,                z);
    1560             :                         glVertex3f(x + 0,                                       y + size_in_pixels.height - pixel_title_size.height + 2,                z);
    1561             :                 OOGLEND();
    1562             :         }
    1563             :         
    1564             :         // draw each row of text
    1565             :         //
    1566             :         OOStartDrawingStrings();
    1567             :         for (i = 0; i < n_rows; i++)
    1568             :         {
    1569             :                 OOColor* row_color = (OOColor *)[rowColor objectAtIndex:i];
    1570             :                 glColor4f([row_color redComponent], [row_color greenComponent], [row_color blueComponent], row_alpha[i]);
    1571             :                 
    1572             :                 if ([[rowText objectAtIndex:i] isKindOfClass:[NSString class]])
    1573             :                 {
    1574             :                         NSString*   text = (NSString *)[rowText objectAtIndex:i];
    1575             :                         if (![text isEqual:@""])
    1576             :                         {
    1577             :                                 strsize = OORectFromString(text, 0.0f, 0.0f, characterSize).size;
    1578             :                                 switch (rowAlignment[i])
    1579             :                                 {
    1580             :                                         case GUI_ALIGN_LEFT :
    1581             :                                                 rowPosition[i].x = 0.0f;
    1582             :                                                 break;
    1583             :                                         case GUI_ALIGN_RIGHT :
    1584             :                                                 rowPosition[i].x = size_in_pixels.width - strsize.width;
    1585             :                                                 break;
    1586             :                                         case GUI_ALIGN_CENTER :
    1587             :                                                 rowPosition[i].x = (size_in_pixels.width - strsize.width)/2.0f;
    1588             :                                                 break;
    1589             :                                 }
    1590             :                                 if (i == (unsigned)selectedRow)
    1591             :                                 {
    1592             :                                         NSRect          block = OORectFromString(text, x + rowPosition[i].x + 2, y + rowPosition[i].y + 2, characterSize);
    1593             :                                         OOStopDrawingStrings();
    1594             :                                         [self setGLColorFromSetting:kGuiSelectedRowBackgroundColor defaultValue:[OOColor redColor] alpha:alpha];
    1595             :                                         OOGLBEGIN(GL_QUADS);
    1596             :                                                 glVertex3f(block.origin.x,                                              block.origin.y,                                         z);
    1597             :                                                 glVertex3f(block.origin.x + block.size.width,   block.origin.y,                                         z);
    1598             :                                                 glVertex3f(block.origin.x + block.size.width,   block.origin.y + block.size.height,     z);
    1599             :                                                 glVertex3f(block.origin.x,                                              block.origin.y + block.size.height,     z);
    1600             :                                         OOGLEND();
    1601             :                                         [self setGLColorFromSetting:kGuiSelectedRowColor defaultValue:[OOColor blackColor] alpha:alpha];
    1602             :                                         OOStartDrawingStrings();
    1603             :                                 }
    1604             :                                 OODrawStringQuadsAligned(text, x + rowPosition[i].x, y + rowPosition[i].y, z, characterSize, NO);
    1605             :                                 
    1606             :                                 // draw cursor at end of current Row
    1607             :                                 //
    1608             :                                 if ((showTextCursor)&&(i == (unsigned)currentRow))
    1609             :                                 {
    1610             :                                         NSRect  tr = OORectFromString(text, 0.0f, 0.0f, characterSize);
    1611             :                                         NSPoint cu = NSMakePoint(x + rowPosition[i].x + tr.size.width + 0.2f * characterSize.width, y + rowPosition[i].y);
    1612             :                                         tr.origin = cu;
    1613             :                                         tr.size.width = 0.5f * characterSize.width;
    1614             :                                         GLfloat g_alpha = 0.5f * (1.0f + (float)sin(6 * [UNIVERSE getTime]));
    1615             :                                         OOStopDrawingStrings();
    1616             :                                         [self setGLColorFromSetting:kGuiTextInputCursorColor defaultValue:[OOColor redColor] alpha:row_alpha[i]*g_alpha];
    1617             :                                         OOGLBEGIN(GL_QUADS);
    1618             :                                                 glVertex3f(tr.origin.x,                                 tr.origin.y,                                    z);
    1619             :                                                 glVertex3f(tr.origin.x + tr.size.width, tr.origin.y,                                    z);
    1620             :                                                 glVertex3f(tr.origin.x + tr.size.width, tr.origin.y + tr.size.height,   z);
    1621             :                                                 glVertex3f(tr.origin.x,                                 tr.origin.y + tr.size.height,   z);
    1622             :                                         OOGLEND();
    1623             :                                         OOStartDrawingStrings();
    1624             :                                 }
    1625             :                         }
    1626             :                 }
    1627             :                 if ([[rowText objectAtIndex:i] isKindOfClass:[NSArray class]])
    1628             :                 {
    1629             :                         NSArray         *array = [rowText oo_arrayAtIndex:i];
    1630             :                         NSUInteger      j, max_columns = MIN([array count], n_columns);
    1631             :                         BOOL            isLeftAligned;
    1632             :                         
    1633             :                         for (j = 0; j < max_columns; j++)
    1634             :                         {
    1635             :                                 NSString*   text = [array oo_stringAtIndex:j];
    1636             :                                 if ([text length] != 0)
    1637             :                                 {
    1638             :                                         isLeftAligned = tabStops[j] >= 0;
    1639             :                                         rowPosition[i].x = labs(tabStops[j]);
    1640             :                                         
    1641             :                                         // we don't want to highlight leading space(s) or narrow spaces (\037s)
    1642             :                                         NSString        *hilitedText = [text stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@" \037"]];
    1643             :                                         NSRange         txtRange = [text rangeOfString:hilitedText];
    1644             :                                         unsigned        leadingSpaces = 0;
    1645             :                                         
    1646             :                                         if (EXPECT_NOT(txtRange.location == NSNotFound))
    1647             :                                         {
    1648             :                                                 // This never happens!
    1649             :                                                 hilitedText = text;
    1650             :                                         }
    1651             :                                         else if (txtRange.location > 0)
    1652             :                                         {
    1653             :                                                 // padded string!
    1654             :                                                 NSRange padRange;
    1655             :                                                 padRange.location = 0;
    1656             :                                                 padRange.length = txtRange.location;
    1657             :                                                 NSRect charBlock = OORectFromString([text substringWithRange:padRange], 0, 0, characterSize);
    1658             :                                                 leadingSpaces = (unsigned)charBlock.size.width;
    1659             : 
    1660             : /*                                              // if we're displaying commodity-quantity-none, let's try and be pixel perfect!
    1661             :                                                 NSString *qtyNone = DESC(@"commodity-quantity-none");
    1662             :                                                 txtRange = [hilitedText rangeOfString:qtyNone];
    1663             :                                                 
    1664             :                                                 if (txtRange.location == 0) // bingo!
    1665             :                                                 {
    1666             :                                                         rowPosition[i].x += OORectFromString(@"0", 0, 0, characterSize).size.width - OORectFromString(qtyNone, 0, 0, characterSize).size.width;
    1667             :                                                         } */
    1668             :                                         }
    1669             :                                         
    1670             :                                         // baseline text rect, needed for correct highlight positioning.
    1671             :                                         NSRect          block = OORectFromString(text, x + rowPosition[i].x + 2, y + rowPosition[i].y + 2, characterSize);
    1672             :                                         
    1673             :                                         if(!isLeftAligned)
    1674             :                                         {
    1675             :                                                 rowPosition[i].x -= block.size.width + 3;
    1676             :                                         }
    1677             :                                         block = OORectFromString(hilitedText, x + rowPosition[i].x + 1 + leadingSpaces, y + rowPosition[i].y + 2, characterSize);
    1678             :                                         block.size.width += 3;
    1679             :                                                 
    1680             :                                         
    1681             :                                         if (i == (unsigned)selectedRow)
    1682             :                                         {
    1683             :                                                 OOStopDrawingStrings();
    1684             :                                                 [self setGLColorFromSetting:kGuiSelectedRowBackgroundColor defaultValue:[OOColor redColor] alpha:alpha];
    1685             :                                                 OOGLBEGIN(GL_QUADS);
    1686             :                                                         glVertex3f(block.origin.x,                                              block.origin.y,                                         z);
    1687             :                                                         glVertex3f(block.origin.x + block.size.width,   block.origin.y,                                         z);
    1688             :                                                         glVertex3f(block.origin.x + block.size.width,   block.origin.y + block.size.height,     z);
    1689             :                                                         glVertex3f(block.origin.x,                                              block.origin.y + block.size.height,     z);
    1690             :                                                 OOGLEND();
    1691             :                                                 [self setGLColorFromSetting:kGuiSelectedRowColor defaultValue:[OOColor blackColor] alpha:alpha];
    1692             :                                                 OOStartDrawingStrings();
    1693             :                                         }
    1694             :                                         OODrawStringQuadsAligned(text, x + rowPosition[i].x, y + rowPosition[i].y, z, characterSize,NO);
    1695             :                                 }
    1696             :                         }
    1697             :                 }
    1698             :         }
    1699             :         OOStopDrawingStrings();
    1700             :         [OOTexture applyNone];
    1701             : }
    1702             : 
    1703             : 
    1704           0 : - (void) drawCrossHairsWithSize:(GLfloat) size x:(GLfloat)x y:(GLfloat)y z:(GLfloat)z
    1705             : {
    1706             :         OOGLBEGIN(GL_QUADS);
    1707             :                 glVertex3f(x - 1,       y - size,       z);
    1708             :                 glVertex3f(x + 1,       y - size,       z);
    1709             :                 glVertex3f(x + 1,       y + size,       z);
    1710             :                 glVertex3f(x - 1,       y + size,       z);
    1711             :                 glVertex3f(x - size,    y - 1,  z);
    1712             :                 glVertex3f(x + size,    y - 1,  z);
    1713             :                 glVertex3f(x + size,    y + 1,  z);
    1714             :                 glVertex3f(x - size,    y + 1,  z);
    1715             :         OOGLEND();
    1716             : }
    1717             : 
    1718             : 
    1719             : - (void) setStarChartTitle
    1720             : {
    1721             :         PlayerEntity *player = PLAYER;
    1722             :         OOGalaxyID galaxy_number = [player galaxyNumber];
    1723             :         NSInteger system_id = [UNIVERSE findSystemNumberAtCoords:[player cursor_coordinates] withGalaxy:[player galaxyNumber] includingHidden:NO];
    1724             : 
    1725             :         NSString *location_key = [NSString stringWithFormat:@"long-range-chart-title-%d-%ld", galaxy_number, (long)system_id];
    1726             :         if ([[UNIVERSE descriptions] valueForKey:location_key] == nil)
    1727             :         {
    1728             :                 NSString *gal_key = [NSString stringWithFormat:@"long-range-chart-title-%d", galaxy_number];
    1729             :                 if ([[UNIVERSE descriptions] valueForKey:gal_key] == nil)
    1730             :                 {
    1731             :                         [self setTitle:[NSString stringWithFormat:DESC(@"long-range-chart-title-d"), galaxy_number+1]];
    1732             :                 }
    1733             :                 else
    1734             :                 {
    1735             :                         [self setTitle:[UNIVERSE descriptionForKey:gal_key]];
    1736             :                 }
    1737             :         }
    1738             :         else
    1739             :         {
    1740             :                 [self setTitle:[UNIVERSE descriptionForKey:location_key]];
    1741             :         }
    1742             : }
    1743             : 
    1744             : 
    1745           0 : - (void) drawStarChart:(GLfloat)x :(GLfloat)y :(GLfloat)z :(GLfloat) alpha :(BOOL)compact
    1746             : {
    1747             :         PlayerEntity* player = PLAYER;
    1748             : 
    1749             :         if (!player)
    1750             :                 return;
    1751             : 
    1752             :         OOSystemDescriptionManager *systemManager = [UNIVERSE systemManager];
    1753             : 
    1754             :         OOScalar        zoom = [player chart_zoom];
    1755             :         NSPoint chart_centre_coordinates = [player adjusted_chart_centre];
    1756             :         NSPoint galaxy_coordinates = [player galaxy_coordinates];
    1757             :         NSPoint cursor_coordinates = [player cursor_coordinates];
    1758             :         NSPoint info_system_coordinates = [[UNIVERSE systemManager] getCoordinatesForSystem: [player infoSystemID] inGalaxy: [player galaxyNumber]];
    1759             :         OOLongRangeChartMode chart_mode = [player longRangeChartMode];
    1760             :         OOGalaxyID              galaxy_id = [player galaxyNumber];
    1761             :         GLfloat                 r = 1.0, g = 1.0, b = 1.0;
    1762             :         BOOL                    noNova;
    1763             :         NSPoint cu;
    1764             :         NSUInteger              systemParameter;
    1765             : 
    1766             :         double fuel = 35.0 * [player dialFuel];
    1767             :         
    1768             :         double          hcenter = size_in_pixels.width/2.0;
    1769             :         double          hscale = size_in_pixels.width / (CHART_WIDTH_AT_MAX_ZOOM*zoom);
    1770             :         double          vscale = -size_in_pixels.height / (2*CHART_HEIGHT_AT_MAX_ZOOM*zoom);
    1771             :         double          vcenter = CHART_SCREEN_VERTICAL_CENTRE;
    1772             :         double          hoffset = hcenter - chart_centre_coordinates.x*hscale;
    1773             :         double          voffset = size_in_pixels.height - vcenter - chart_centre_coordinates.y*vscale;
    1774             : 
    1775             :         if (compact)
    1776             :         {
    1777             :                 hscale = size_in_pixels.width / 256.0;
    1778             :                 vscale = -1.0 * size_in_pixels.height / 512.0;
    1779             :                 hoffset = 0.0f;
    1780             :                 voffset = size_in_pixels.height - pixel_title_size.height - 5;
    1781             :                 vcenter = CHART_SCREEN_VERTICAL_CENTRE_COMPACT;
    1782             :                 chart_centre_coordinates.x = 128.0;
    1783             :                 chart_centre_coordinates.y = 128.0;
    1784             :                 zoom = CHART_MAX_ZOOM;
    1785             :         }
    1786             :         
    1787             :         int                     i;
    1788             :         double          d, distance = 0.0, time = 0.0;
    1789             :         int             jumps = 0;
    1790             :         NSPoint         star;
    1791             :         OOScalar        pixelRatio;
    1792             :         NSRect          clipRect;
    1793             :         
    1794             :         OORouteType     advancedNavArrayMode = [player ANAMode];
    1795             :         BOOL            routeExists = NO;
    1796             : 
    1797             :         NSInteger concealment[256];
    1798             :         for (i=0;i<256;i++) {
    1799             :                 NSDictionary *systemInfo = [systemManager getPropertiesForSystem:i inGalaxy:galaxy_id];
    1800             :                 concealment[i] = [systemInfo oo_intForKey:@"concealment" defaultValue:OO_SYSTEMCONCEALMENT_NONE];
    1801             :         }
    1802             :         
    1803             :         BOOL            *systemsFound = [UNIVERSE systemsFound];
    1804             :         NSSize          viewSize = [[UNIVERSE gameView] backingViewSize];
    1805             :         double aspect_ratio = viewSize.width / viewSize.height;
    1806             : 
    1807             :         // default colours - match those in HeadUpDisplay:OODrawPlanetInfo
    1808             :         GLfloat govcol[] = {    0.5, 0.0, 0.7,
    1809             :                                                         0.7, 0.5, 0.3,
    1810             :                                                         0.0, 1.0, 0.3,
    1811             :                                                         1.0, 0.8, 0.1,
    1812             :                                                         1.0, 0.0, 0.0,
    1813             :                                                         0.1, 0.5, 1.0,
    1814             :                                                         0.7, 0.7, 0.7,
    1815             :                                                         0.7, 1.0, 1.0};
    1816             : 
    1817             :         if (aspect_ratio > 4.0/3.0)
    1818             :         {
    1819             :                 pixelRatio = viewSize.height / 480.0;
    1820             :         }
    1821             :         else
    1822             :         {
    1823             :                 pixelRatio = viewSize.width / 640.0;
    1824             :         }
    1825             : 
    1826             :         NSInteger textRow = compact ? GUI_ROW_CHART_SYSTEM_COMPACT : GUI_ROW_CHART_SYSTEM;
    1827             :         
    1828             :         clipRect = NSMakeRect((viewSize.width - size_in_pixels.width*pixelRatio)/2.0,
    1829             :                                 (viewSize.height + size_in_pixels.height*pixelRatio)/2.0 - (pixel_title_size.height + 15 + (textRow-2)*MAIN_GUI_ROW_HEIGHT) * pixelRatio,
    1830             :                                 size_in_pixels.width * pixelRatio,
    1831             :                                 (textRow-1) * MAIN_GUI_ROW_HEIGHT * pixelRatio);
    1832             : 
    1833             :         OOSystemID target = [PLAYER targetSystemID];
    1834             :         double dx, dy;
    1835             :         
    1836             :         // get a list of systems marked as contract destinations
    1837             :         NSDictionary* markedDestinations = [player markedDestinations];
    1838             :         
    1839             :         // get present location
    1840             :         cu = NSMakePoint((float)(hscale*galaxy_coordinates.x+hoffset),(float)(vscale*galaxy_coordinates.y+voffset));
    1841             : 
    1842             :         // enable draw clipping; limit drawing area within the chart area
    1843             :         OOGL(glEnable(GL_SCISSOR_TEST));
    1844             :         OOGL(glScissor(clipRect.origin.x, clipRect.origin.y, clipRect.size.width, clipRect.size.height));
    1845             : 
    1846             :         // Cache nearby systems so that [UNIVERSE generateSystemData:] does not get called on every frame
    1847             :         // Caching code submitted by Y A J, 20091022
    1848             :         
    1849             :         static OOGalaxyID saved_galaxy_id;
    1850             :         static struct saved_system
    1851             :         {
    1852             :                 OOSystemID sysid;
    1853             :                 int tec, eco, gov;
    1854             :                 NSString* p_name;
    1855             :                 BOOL nova;
    1856             :         } nearby_systems[ 256 ];
    1857             :         static int num_nearby_systems = 0;
    1858             : 
    1859             :         if ( _refreshStarChart || galaxy_id != saved_galaxy_id)
    1860             :         {
    1861             :                 // saved systems are stale; recompute
    1862             :                 _refreshStarChart = NO;
    1863             :                 for (i = 0; i < num_nearby_systems; i++)
    1864             :                         [nearby_systems[ i ].p_name release];
    1865             : 
    1866             :                 num_nearby_systems = 0;
    1867             :                 for (i = 0; i < 256; i++)
    1868             :                 {
    1869             : 
    1870             :                         NSDictionary* sys_info = [UNIVERSE generateSystemData:i];
    1871             :                         if (EXPECT_NOT([sys_info oo_boolForKey:@"sun_gone_nova"]))
    1872             :                         {
    1873             :                                 nearby_systems[ num_nearby_systems ].gov = -1;  // Flag up nova systems!
    1874             :                         }
    1875             :                         else
    1876             :                         {
    1877             :                                 nearby_systems[ num_nearby_systems ].tec = [sys_info oo_intForKey:KEY_TECHLEVEL];
    1878             :                                 nearby_systems[ num_nearby_systems ].eco = [sys_info oo_intForKey:KEY_ECONOMY];
    1879             :                                 nearby_systems[ num_nearby_systems ].gov = [sys_info oo_intForKey:KEY_GOVERNMENT];
    1880             :                         }
    1881             :                         nearby_systems[ num_nearby_systems ].sysid = i;
    1882             :                         nearby_systems[ num_nearby_systems ].p_name = [[sys_info oo_stringForKey:KEY_NAME] retain];
    1883             :                         nearby_systems[ num_nearby_systems ].nova = [[UNIVERSE generateSystemData:i] oo_boolForKey:@"sun_gone_nova"];
    1884             :                         num_nearby_systems++;
    1885             :                 }
    1886             :                 saved_galaxy_id = [player galaxyNumber];
    1887             :         }
    1888             :         
    1889             :         static OOSystemID savedPlanetNumber = 0;
    1890             :         static OOSystemID savedDestNumber = 0;
    1891             :         static OORouteType savedArrayMode = OPTIMIZED_BY_NONE;
    1892             :         static NSDictionary *routeInfo = nil;
    1893             : 
    1894             :         /* May override current mode for mission screens */
    1895             :         if (backgroundSpecial == GUI_BACKGROUND_SPECIAL_LONG_ANA_SHORTEST || 
    1896             :                 backgroundSpecial == GUI_BACKGROUND_SPECIAL_SHORT_ANA_SHORTEST || 
    1897             :                 backgroundSpecial == GUI_BACKGROUND_SPECIAL_CUSTOM_ANA_SHORTEST)
    1898             :         {
    1899             :                 advancedNavArrayMode = OPTIMIZED_BY_JUMPS;
    1900             :         }
    1901             :         else if (backgroundSpecial == GUI_BACKGROUND_SPECIAL_LONG_ANA_QUICKEST ||
    1902             :                 backgroundSpecial == GUI_BACKGROUND_SPECIAL_SHORT_ANA_QUICKEST ||
    1903             :                 backgroundSpecial == GUI_BACKGROUND_SPECIAL_CUSTOM_ANA_QUICKEST)
    1904             :         {
    1905             :                 advancedNavArrayMode = OPTIMIZED_BY_TIME;
    1906             :         }
    1907             :         
    1908             :         if (advancedNavArrayMode != OPTIMIZED_BY_NONE && [player hasEquipmentItemProviding:@"EQ_ADVANCED_NAVIGATIONAL_ARRAY"])
    1909             :         {
    1910             :                 OOSystemID planetNumber = [PLAYER systemID];
    1911             :                 OOSystemID destNumber = [PLAYER targetSystemID];
    1912             :                 if (routeInfo == nil || planetNumber != savedPlanetNumber || destNumber != savedDestNumber || advancedNavArrayMode != savedArrayMode)
    1913             :                 {
    1914             :                         [routeInfo release];
    1915             :                         routeInfo = [[UNIVERSE routeFromSystem:planetNumber toSystem:destNumber optimizedBy:advancedNavArrayMode] retain];
    1916             :                         savedPlanetNumber = planetNumber;
    1917             :                         savedDestNumber = destNumber;
    1918             :                         savedArrayMode = advancedNavArrayMode;
    1919             :                 }
    1920             :                 target = destNumber;
    1921             :                 
    1922             :                 // if the ANA has been activated and we are in string input mode (i.e. planet search),
    1923             :                 // get out of it so that distance and time data can be displayed
    1924             :                 //if ([[[UNIVERSE gameView] typedString] length] > 0)  [player clearPlanetSearchString];
    1925             :                 
    1926             :                 if (routeInfo)  routeExists = YES;
    1927             :                 
    1928             :                 [self drawAdvancedNavArrayAtX:x+hoffset y:y+voffset z:z alpha:alpha usingRoute: (planetNumber != destNumber ? (id)routeInfo : nil) optimizedBy:advancedNavArrayMode zoom: zoom];
    1929             : 
    1930             :                 if (routeExists)
    1931             :                 {
    1932             :                         distance = [routeInfo oo_doubleForKey:@"distance"];
    1933             :                         time = [routeInfo oo_doubleForKey:@"time"];
    1934             :                         jumps = [routeInfo oo_intForKey:@"jumps"];
    1935             : 
    1936             :                         if (distance == 0.0 && planetNumber != destNumber)
    1937             :                         {
    1938             :                                 // zero-distance double fix
    1939             :                                 distance = 0.1;
    1940             :                                 time = 0.01;
    1941             :                         }
    1942             :                 }
    1943             :         }
    1944             :         else
    1945             :         {
    1946             :                 [self drawAdvancedNavArrayAtX:x+hoffset y:y+voffset z:z alpha:alpha usingRoute:nil optimizedBy:OPTIMIZED_BY_NONE zoom: zoom];
    1947             :         }
    1948             :         if (!routeExists)
    1949             :         {
    1950             :                 NSPoint targetCoordinates = [systemManager getCoordinatesForSystem:target inGalaxy:galaxy_id];
    1951             : 
    1952             :                 distance = distanceBetweenPlanetPositions(targetCoordinates.x,targetCoordinates.y,galaxy_coordinates.x,galaxy_coordinates.y);
    1953             :                 if (distance == 0.0)
    1954             :                 {
    1955             :                         if (target != [PLAYER systemID])
    1956             :                         {
    1957             :                                 // looking at the other half of a zero-distance double
    1958             :                                 // distance is treated as 0.1 LY
    1959             :                                 distance = 0.1;
    1960             :                         }
    1961             :                 }
    1962             :                 if ([player hasHyperspaceMotor] && distance <= [player fuel]/10.0)
    1963             :                 {
    1964             :                         time = distance * distance;
    1965             :                 }
    1966             :                 else
    1967             :                 {
    1968             :                         time = 0.0;
    1969             :                 }
    1970             :         }
    1971             : 
    1972             :         if ([player hasHyperspaceMotor])
    1973             :         {
    1974             :                 // draw fuel range circle
    1975             :                 OOGL(GLScaledLineWidth(2.0f));
    1976             :                 [self setGLColorFromSetting:kGuiChartRangeColor defaultValue:[OOColor greenColor] alpha:alpha];
    1977             :                                                 
    1978             :                 GLDrawOval(x + cu.x, y + cu.y, z, NSMakeSize((float)(fuel*hscale), 2*(float)(fuel*vscale)), 5);
    1979             :         }
    1980             : 
    1981             :         
    1982             :         // draw crosshairs over current location
    1983             :         //
    1984             :         [self setGLColorFromSetting:kGuiChartCrosshairColor defaultValue:[OOColor greenColor] alpha:alpha];
    1985             : 
    1986             :         [self drawCrossHairsWithSize:12/zoom+2 x:x + cu.x y:y + cu.y z:z];
    1987             : 
    1988             : 
    1989             :         // draw crosshairs over cursor
    1990             :         //
    1991             :         [self setGLColorFromSetting:kGuiChartCursorColor defaultValue:[OOColor redColor] alpha:alpha];
    1992             :         cu = NSMakePoint((float)(hscale*cursor_coordinates.x+hoffset),(float)(vscale*cursor_coordinates.y+voffset));
    1993             :         [self drawCrossHairsWithSize:7/zoom+2 x:x + cu.x y:y + cu.y z:z];
    1994             : 
    1995             :         // draw marks and stars
    1996             :         //
    1997             :         OOGL(GLScaledLineWidth(1.5f));
    1998             :         OOGL(glColor4f(1.0f, 1.0f, 0.75f, alpha));      // pale yellow
    1999             : 
    2000             :         for (i = 0; i < num_nearby_systems; i++)
    2001             :         {
    2002             :                 NSPoint sys_coordinates = [systemManager getCoordinatesForSystem:i inGalaxy:galaxy_id];
    2003             :                 
    2004             :                 dx = fabs(chart_centre_coordinates.x - sys_coordinates.x);
    2005             :                 dy = fabs(chart_centre_coordinates.y - sys_coordinates.y);
    2006             :         
    2007             :                 if ((dx > zoom*(CHART_WIDTH_AT_MAX_ZOOM/2.0 + CHART_CLIP_BORDER))||(dy > zoom*(CHART_HEIGHT_AT_MAX_ZOOM + CHART_CLIP_BORDER)))
    2008             :                         continue;
    2009             : 
    2010             : 
    2011             :                 if (concealment[i] >= OO_SYSTEMCONCEALMENT_NOTHING) {
    2012             :                         // system is not known
    2013             :                         continue;
    2014             :                 }
    2015             : 
    2016             :                 NSDictionary *systemInfo = [systemManager getPropertiesForSystem:i inGalaxy:galaxy_id];
    2017             :                 float blob_factor = [guiUserSettings oo_floatForKey:kGuiChartCircleScale defaultValue:0.0017];
    2018             :                 float blob_size = (1.0f + blob_factor * [systemInfo oo_floatForKey:@"radius"])/zoom;
    2019             :                 if (blob_size < 0.5) blob_size = 0.5;
    2020             : 
    2021             :                 star.x = (float)(sys_coordinates.x * hscale + hoffset);
    2022             :                 star.y = (float)(sys_coordinates.y * vscale + voffset);
    2023             : 
    2024             :                 noNova = !nearby_systems[i].nova;
    2025             :                 NSAssert1(chart_mode <= OOLRC_MODE_TECHLEVEL, @"Long range chart mode %i out of range", (int)chart_mode);
    2026             :         
    2027             :                 NSArray *markers = [markedDestinations objectForKey:[NSNumber numberWithInt:i]];
    2028             :                 if (markers != nil)     // is marked
    2029             :                 {
    2030             :                         GLfloat base_size = 0.5f * blob_size + 2.5f;
    2031             :                         [self drawSystemMarkers:markers atX:x+star.x andY:y+star.y andZ:z withAlpha:alpha andScale:base_size];
    2032             :                 }
    2033             : 
    2034             :                 if (concealment[i] >= OO_SYSTEMCONCEALMENT_NODATA) {
    2035             :                         // no system data available
    2036             :                         r = g = b = 0.7;
    2037             :                         OOGL(glColor4f(r, g, b, alpha));
    2038             :                 } else {
    2039             :                         switch (chart_mode)
    2040             :                         {
    2041             :                         case OOLRC_MODE_ECONOMY:
    2042             :                                 if (EXPECT(noNova))
    2043             :                                 {
    2044             :                                         systemParameter = nearby_systems[i].eco;
    2045             :                                         GLfloat ce1 = 1.0f - 0.125f * systemParameter;
    2046             :                                         [self setGLColorFromSetting:[NSString stringWithFormat:kGuiChartEconomyUColor, (unsigned long)systemParameter]
    2047             :                                                                    defaultValue:[OOColor colorWithRed:ce1 green:1.0f blue:0.0f alpha:1.0f] 
    2048             :                                                                                   alpha:1.0];
    2049             :                                 }
    2050             :                                 else
    2051             :                                 {
    2052             :                                         r = g = b = 0.3;
    2053             :                                         OOGL(glColor4f(r, g, b, alpha));
    2054             :                                 }
    2055             :                                 break;
    2056             :                         case OOLRC_MODE_GOVERNMENT:
    2057             :                                 if (EXPECT(noNova))
    2058             :                                 {
    2059             :                                         systemParameter = nearby_systems[i].gov;
    2060             :                                         [self setGLColorFromSetting:[NSString stringWithFormat:kGuiChartGovernmentUColor, (unsigned long)systemParameter]
    2061             :                                                                    defaultValue:[OOColor colorWithRed:govcol[systemParameter*3] green:govcol[1+(systemParameter*3)] blue:govcol[2+(systemParameter*3)] alpha:1.0f] 
    2062             :                                                                                   alpha:1.0];
    2063             :                                 }
    2064             :                                 else
    2065             :                                 {
    2066             :                                         r = g = b = 0.3;
    2067             :                                         OOGL(glColor4f(r, g, b, alpha));
    2068             :                                 }
    2069             :                                 break;
    2070             :                         case OOLRC_MODE_TECHLEVEL:
    2071             :                                 if (EXPECT(noNova))
    2072             :                                 {
    2073             :                                         systemParameter = nearby_systems[i].tec;
    2074             :                                         r = 0.6;
    2075             :                                         g = b = 0.20 + (0.05 * (GLfloat)systemParameter);
    2076             :                                 }
    2077             :                                 else
    2078             :                                 {
    2079             :                                         r = g = b = 0.3;
    2080             :                                 }                       
    2081             :                                 OOGL(glColor4f(r, g, b, alpha));
    2082             :                                 break;
    2083             :                         case OOLRC_MODE_UNKNOWN:
    2084             :                         case OOLRC_MODE_SUNCOLOR:
    2085             :                                 if (EXPECT(noNova))
    2086             :                                 {
    2087             :                                         r = g = b = 1.0;
    2088             :                                         OOColor *sunColor = [OOColor colorWithDescription:[[UNIVERSE systemManager] getProperty:@"sun_color" forSystem:i inGalaxy:galaxy_id]];
    2089             :                                         if (sunColor != nil) {
    2090             :                                                 [sunColor getRed:&r green:&g blue:&b alpha:&alpha];
    2091             :                                                 alpha = 1.0; // reset
    2092             :                                         }
    2093             :                                 }
    2094             :                                 else
    2095             :                                 {
    2096             :                                         r = 1.0;
    2097             :                                         g = 0.2;
    2098             :                                         b = 0.0;
    2099             :                                 }
    2100             :                                 OOGL(glColor4f(r, g, b, alpha));
    2101             :                                 break;
    2102             :                         }
    2103             :                 }
    2104             :                 
    2105             :                 GLDrawFilledOval(x + star.x, y + star.y, z, NSMakeSize(blob_size,blob_size), 15);
    2106             :         }
    2107             :         
    2108             :         // draw found stars and captions
    2109             :         //
    2110             :         GLfloat systemNameScale = [guiUserSettings oo_floatForKey:kGuiChartLabelScale defaultValue:1.0];
    2111             : 
    2112             :         OOGL(GLScaledLineWidth(1.5f));
    2113             :         [self setGLColorFromSetting:kGuiChartMatchBoxColor defaultValue:[OOColor greenColor] alpha:alpha];
    2114             : 
    2115             :         int n_matches = 0, foundIndex = -1;
    2116             :         
    2117             :         for (i = 0; i < 256; i++) if (systemsFound[i])
    2118             :         {
    2119             :                 if(foundSystem == n_matches) foundIndex = i;
    2120             :                 n_matches++;
    2121             :         }
    2122             :         
    2123             :         if (n_matches == 0)
    2124             :         {
    2125             :                 foundSystem = 0;
    2126             :         }
    2127             :         else if (backgroundSpecial == GUI_BACKGROUND_SPECIAL_LONG_ANA_SHORTEST || backgroundSpecial == GUI_BACKGROUND_SPECIAL_LONG_ANA_QUICKEST || backgroundSpecial == GUI_BACKGROUND_SPECIAL_LONG)
    2128             :         {
    2129             :                 // do nothing at this stage
    2130             :         }
    2131             :         else
    2132             :         {
    2133             :                 for (i = 0; i < 256; i++)
    2134             :                 {
    2135             :                         if (concealment[i] >= OO_SYSTEMCONCEALMENT_NONAME)
    2136             :                         {
    2137             :                                 continue;
    2138             :                         }
    2139             :                         
    2140             :                         BOOL mark = systemsFound[i];
    2141             :                         float marker_size = 8.0/zoom;
    2142             :                         NSPoint sys_coordinates = [systemManager getCoordinatesForSystem:i inGalaxy:galaxy_id];
    2143             : 
    2144             :                         dx = fabs(chart_centre_coordinates.x - sys_coordinates.x);
    2145             :                         dy = fabs(chart_centre_coordinates.y - sys_coordinates.y);
    2146             :                 
    2147             :                         if (mark && (dx <= zoom*(CHART_WIDTH_AT_MAX_ZOOM/2.0+CHART_CLIP_BORDER))&&(dy <= zoom*(CHART_HEIGHT_AT_MAX_ZOOM+CHART_CLIP_BORDER)))
    2148             :                         {
    2149             :                                 star.x = (float)(sys_coordinates.x * hscale + hoffset);
    2150             :                                 star.y = (float)(sys_coordinates.y * vscale + voffset);
    2151             :                                 OOGLBEGIN(GL_LINE_LOOP);
    2152             :                                         glVertex3f(x + star.x - marker_size,    y + star.y - marker_size,       z);
    2153             :                                         glVertex3f(x + star.x + marker_size,    y + star.y - marker_size,       z);
    2154             :                                         glVertex3f(x + star.x + marker_size,    y + star.y + marker_size,       z);
    2155             :                                         glVertex3f(x + star.x - marker_size,    y + star.y + marker_size,       z);
    2156             :                                 OOGLEND();
    2157             :                                 if (i == foundIndex || n_matches == 1)
    2158             :                                 {
    2159             :                                         if (n_matches == 1) foundSystem = 0;
    2160             :                                         if (zoom > CHART_ZOOM_SHOW_LABELS && advancedNavArrayMode == OPTIMIZED_BY_NONE)
    2161             :                                         {
    2162             :                                                 [self setGLColorFromSetting:kGuiChartMatchLabelColor defaultValue:[OOColor cyanColor] alpha:alpha];
    2163             :                                                 OODrawString([UNIVERSE systemNameIndex:i] , x + star.x + 2.0, y + star.y - 10.0f, z, NSMakeSize(10*systemNameScale,10*systemNameScale));
    2164             :                                                 [self setGLColorFromSetting:kGuiChartMatchBoxColor defaultValue:[OOColor greenColor] alpha:alpha];
    2165             :                                         }
    2166             :                                 }
    2167             :                                 else if (zoom > CHART_ZOOM_SHOW_LABELS)
    2168             :                                 {
    2169             :                                         OODrawString([UNIVERSE systemNameIndex:i] , x + star.x + 2.0, y + star.y - 10.0f, z, NSMakeSize(10*systemNameScale,10*systemNameScale));
    2170             :                                 }
    2171             :                         }
    2172             :                 }
    2173             :         }
    2174             : 
    2175             :         // draw names
    2176             :         //
    2177             : //      OOGL(glColor4f(1.0f, 1.0f, 0.0f, alpha));       // yellow
    2178             :         
    2179             :         int targetIdx = -1;
    2180             :         struct saved_system *sys;
    2181             :         NSSize chSize = NSMakeSize(pixel_row_height*systemNameScale/zoom,pixel_row_height*systemNameScale/zoom);
    2182             :         
    2183             :         double jumpRange = MAX_JUMP_RANGE * [PLAYER dialFuel];
    2184             :         for (i = 0; i < num_nearby_systems; i++)
    2185             :         {
    2186             :                 if (concealment[i] >= OO_SYSTEMCONCEALMENT_NONAME)
    2187             :                 {
    2188             :                         continue;
    2189             :                 }
    2190             : 
    2191             :                 sys = nearby_systems + i;
    2192             :                 NSPoint sys_coordinates = [systemManager getCoordinatesForSystem:sys->sysid inGalaxy:galaxy_id];
    2193             : 
    2194             :                 dx = fabs(chart_centre_coordinates.x - sys_coordinates.x);
    2195             :                 dy = fabs(chart_centre_coordinates.y - sys_coordinates.y);
    2196             :                 
    2197             :                 if ((dx > zoom*(CHART_WIDTH_AT_MAX_ZOOM/2.0+CHART_CLIP_BORDER))||(dy > zoom*(CHART_HEIGHT_AT_MAX_ZOOM+CHART_CLIP_BORDER)))
    2198             :                         continue;
    2199             :                 star.x = (float)(sys_coordinates.x * hscale + hoffset);
    2200             :                 star.y = (float)(sys_coordinates.y * vscale + voffset);
    2201             :                 if (sys->sysid == target)            // not overlapping twin? (example: Divees & Tezabi in galaxy 5)
    2202             :                 {
    2203             :                          targetIdx = i;         // we have a winner!
    2204             :                 }
    2205             : 
    2206             : 
    2207             :                 
    2208             :                 if (zoom < CHART_ZOOM_SHOW_LABELS)
    2209             :                 {
    2210             :                         if (![player showInfoFlag])     // System's name
    2211             :                         {
    2212             : 
    2213             :                                 d = distanceBetweenPlanetPositions(galaxy_coordinates.x, galaxy_coordinates.y, sys_coordinates.x, sys_coordinates.y);
    2214             :                                 if (d <= jumpRange)
    2215             :                                 {
    2216             :                                         [self setGLColorFromSetting:kGuiChartLabelReachableColor defaultValue:[OOColor yellowColor] alpha:alpha];
    2217             :                                 }
    2218             :                                 else
    2219             :                                 {
    2220             :                                         [self setGLColorFromSetting:kGuiChartLabelColor defaultValue:[OOColor yellowColor] alpha:alpha];
    2221             : 
    2222             :                                 }
    2223             : 
    2224             :                                 OODrawString(sys->p_name, x + star.x + 2.0, y + star.y, z, chSize);
    2225             :                         }
    2226             :                         else if (EXPECT(sys->gov >= 0))   // Not a nova? Show the info.
    2227             :                         {
    2228             :                                 if (concealment[i] >= OO_SYSTEMCONCEALMENT_NODATA)
    2229             :                                 {
    2230             :                                         [self setGLColorFromSetting:kGuiChartLabelColor defaultValue:[OOColor yellowColor] alpha:alpha];
    2231             :                                         OODrawHilightedString(@"???", x + star.x + 2.0, y + star.y, z, chSize);
    2232             :                                 }
    2233             :                                 else
    2234             :                                 {
    2235             :                                         OODrawPlanetInfo(sys->gov, sys->eco, sys->tec, x + star.x + 2.0, y + star.y + 2.0, z, chSize);
    2236             :                                 }
    2237             :                         }
    2238             :                 }
    2239             :         }
    2240             :         
    2241             :         // highlight the name of the currently selected system
    2242             :         // (needed to get things right in closely-overlapping systems)
    2243             :         if( targetIdx != -1 && zoom <= CHART_ZOOM_SHOW_LABELS)
    2244             :         {
    2245             :                 if (concealment[targetIdx] < OO_SYSTEMCONCEALMENT_NONAME)
    2246             :                 {
    2247             :                         sys = nearby_systems + targetIdx;
    2248             :                         NSPoint sys_coordinates = [systemManager getCoordinatesForSystem:sys->sysid inGalaxy:galaxy_id];
    2249             : 
    2250             :                         star.x = (float)(sys_coordinates.x * hscale + hoffset);
    2251             :                         star.y = (float)(sys_coordinates.y * vscale + voffset);
    2252             :                 
    2253             :                         if (![player showInfoFlag])
    2254             :                         {
    2255             :                                 d = distanceBetweenPlanetPositions(galaxy_coordinates.x, galaxy_coordinates.y, sys_coordinates.x, sys_coordinates.y);
    2256             :                                 if (d <= jumpRange)
    2257             :                                 {
    2258             :                                         [self setGLColorFromSetting:kGuiChartLabelReachableColor defaultValue:[OOColor yellowColor] alpha:alpha];
    2259             :                                 }
    2260             :                                 else
    2261             :                                 {
    2262             :                                         [self setGLColorFromSetting:kGuiChartLabelColor defaultValue:[OOColor yellowColor] alpha:alpha];
    2263             :                                 
    2264             :                                 }
    2265             : 
    2266             :                                 OODrawHilightedString(sys->p_name, x + star.x + 2.0, y + star.y, z, chSize);
    2267             :                         }
    2268             :                         else if (sys->gov >= 0)   // Not a nova? Show the info.
    2269             :                         {
    2270             :                                 if (concealment[targetIdx] >= OO_SYSTEMCONCEALMENT_NODATA)
    2271             :                                 {
    2272             :                                         [self setGLColorFromSetting:kGuiChartLabelColor defaultValue:[OOColor yellowColor] alpha:alpha];
    2273             :                                         OODrawHilightedString(@"???", x + star.x + 2.0, y + star.y, z, chSize);
    2274             :                                 }
    2275             :                                 else
    2276             :                                 {
    2277             :                                         OODrawHilightedPlanetInfo(sys->gov, sys->eco, sys->tec, x + star.x + 2.0, y + star.y + 2.0, z, chSize);
    2278             :                                 }
    2279             :                         }
    2280             :                 }
    2281             :         }
    2282             :         
    2283             :         OOGUITabSettings tab_stops;
    2284             :         tab_stops[0] = 0;
    2285             :         tab_stops[1] = 96;
    2286             :         tab_stops[2] = 288;
    2287             :         [self overrideTabs:tab_stops from:kGuiChartTraveltimeTabs length:3];
    2288             :         [self setTabStops:tab_stops];
    2289             :         NSString *targetName = [[UNIVERSE getSystemName:target] retain];
    2290             : 
    2291             :         // distance-f & est-travel-time-f are identical between short & long range charts in standard Oolite, however can be alterered separately via OXPs
    2292             :         NSString *travelDistLine = @"";
    2293             :         if (distance > 0)
    2294             :         {
    2295             :                 travelDistLine = OOExpandKey(@"long-range-chart-distance", distance);
    2296             :         }
    2297             :         NSString *travelTimeLine = @"";
    2298             :         if (time > 0)
    2299             :         {
    2300             :                 travelTimeLine = OOExpandKey(@"long-range-chart-est-travel-time", time);
    2301             :         }
    2302             :         
    2303             :         if(concealment[target] < OO_SYSTEMCONCEALMENT_NONAME)
    2304             :         {
    2305             :                 [self setArray:[NSArray arrayWithObjects:targetName, travelDistLine,travelTimeLine,nil] forRow:textRow];
    2306             :         }
    2307             :         else
    2308             :         {
    2309             :                 [self setArray:[NSArray arrayWithObjects:@"", travelDistLine,travelTimeLine,nil] forRow:textRow];
    2310             :         }
    2311             :         if ([PLAYER guiScreen] == GUI_SCREEN_SHORT_RANGE_CHART)
    2312             :         {
    2313             :                 if (jumps > 0)
    2314             :                 {
    2315             :                         [self setArray:[NSArray arrayWithObjects: @"", OOExpandKey(@"short-range-chart-jumps", jumps), nil] forRow: textRow + 1];
    2316             :                 }
    2317             :                 else
    2318             :                 {
    2319             :                         [self setArray:[NSArray array] forRow: textRow + 1];
    2320             :                 }
    2321             :         }
    2322             :         [targetName release];
    2323             : 
    2324             :         // draw planet info circle
    2325             :         OOGL(GLScaledLineWidth(2.0f));
    2326             :         [self setGLColorFromSetting: kGuiChartInfoMarkerColor defaultValue:[OOColor blueColor] alpha:alpha];
    2327             :         cu = NSMakePoint((float)(hscale*info_system_coordinates.x+hoffset),(float)(vscale*info_system_coordinates.y+voffset));
    2328             :         GLDrawOval(x + cu.x, y + cu.y, z, NSMakeSize(6.0f/zoom+2.0f, 6.0f/zoom+2.0f), 5);
    2329             : 
    2330             :         // disable draw clipping
    2331             :         OOGL(glDisable(GL_SCISSOR_TEST));
    2332             : 
    2333             :         // Draw bottom divider
    2334             :         [self setGLColorFromSetting:kGuiScreenDividerColor defaultValue:[OOColor colorWithWhite:0.75 alpha:1.0] alpha:alpha];
    2335             :         OOGLBEGIN(GL_QUADS);
    2336             :                 glVertex3f(x + 0, (float)(y + size_in_pixels.height - (textRow-1)*MAIN_GUI_ROW_HEIGHT - pixel_title_size.height),       z);
    2337             :                 glVertex3f(x + size_in_pixels.width, (GLfloat)(y + size_in_pixels.height - (textRow-1)*MAIN_GUI_ROW_HEIGHT - pixel_title_size.height), z);
    2338             :                 glVertex3f(x + size_in_pixels.width, (GLfloat)(y + size_in_pixels.height - (textRow-1)*MAIN_GUI_ROW_HEIGHT - pixel_title_size.height - 2), z);
    2339             :                 glVertex3f(x + 0, (GLfloat)(y + size_in_pixels.height - (textRow-1)*MAIN_GUI_ROW_HEIGHT - pixel_title_size.height - 2), z);
    2340             :         OOGLEND();
    2341             : }
    2342             : 
    2343             : 
    2344           0 : - (void) drawSystemMarkers:(NSArray *)markers atX:(GLfloat)x andY:(GLfloat)y andZ:(GLfloat)z withAlpha:(GLfloat)alpha andScale:(GLfloat)scale
    2345             : {
    2346             :         NSEnumerator *mEnum; 
    2347             :         NSDictionary *marker;
    2348             :         for (mEnum = [markers objectEnumerator]; (marker = [mEnum nextObject]); )
    2349             :         {
    2350             :                 [self drawSystemMarker:marker atX:x andY:y andZ:z withAlpha:alpha andScale:scale];
    2351             :         }
    2352             : }
    2353             : 
    2354             : 
    2355           0 : - (void) drawSystemMarker:(NSDictionary *)marker atX:(GLfloat)x andY:(GLfloat)y andZ:(GLfloat)z withAlpha:(GLfloat)alpha andScale:(GLfloat)scale
    2356             : {
    2357             :         NSString *colorDesc = [marker oo_stringForKey:@"markerColor" defaultValue:@"redColor"];
    2358             :         OORGBAComponents color = [[OOColor colorWithDescription:colorDesc] rgbaComponents];
    2359             :         
    2360             :         OOGL(glColor4f(color.r, color.g, color.b, alpha));      // red
    2361             :         GLfloat mark_size = [marker oo_floatForKey:@"markerScale" defaultValue:1.0];
    2362             :         if (mark_size > 2.0)
    2363             :         {
    2364             :                 mark_size = 2.0;
    2365             :         }
    2366             :         else if (mark_size < 0.5)
    2367             :         {
    2368             :                 mark_size = 0.5;
    2369             :         }
    2370             :         mark_size *= scale;
    2371             : 
    2372             :         NSString *shape = [marker oo_stringForKey:@"markerShape" defaultValue:@"MARKER_X"];
    2373             : 
    2374             :         OOGLBEGIN(GL_LINES);
    2375             :         if ([shape isEqualToString:@"MARKER_X"])
    2376             :         {
    2377             :                 glVertex3f(x - mark_size,       y - mark_size,  z);
    2378             :                 glVertex3f(x + mark_size,       y + mark_size,  z);
    2379             :                 glVertex3f(x - mark_size,       y + mark_size,  z);
    2380             :                 glVertex3f(x + mark_size,       y - mark_size,  z);
    2381             :         }
    2382             :         else if ([shape isEqualToString:@"MARKER_PLUS"])
    2383             :         {
    2384             :                 mark_size *= 1.4; // match volumes
    2385             :                 glVertex3f(x,   y - mark_size,  z);
    2386             :                 glVertex3f(x,   y + mark_size,  z);
    2387             :                 glVertex3f(x - mark_size,       y,      z);
    2388             :                 glVertex3f(x + mark_size,       y,      z);
    2389             :         }
    2390             :         else if ([shape isEqualToString:@"MARKER_SQUARE"])
    2391             :         {
    2392             :                 glVertex3f(x - mark_size,       y - mark_size,  z);
    2393             :                 glVertex3f(x - mark_size,       y + mark_size,  z);
    2394             :                 glVertex3f(x - mark_size,       y + mark_size,  z);
    2395             :                 glVertex3f(x + mark_size,       y + mark_size,  z);
    2396             :                 glVertex3f(x + mark_size,       y + mark_size,  z);
    2397             :                 glVertex3f(x + mark_size,       y - mark_size,  z);
    2398             :                 glVertex3f(x + mark_size,       y - mark_size,  z);
    2399             :                 glVertex3f(x - mark_size,       y - mark_size,  z);
    2400             :         }
    2401             :         else if ([shape isEqualToString:@"MARKER_DIAMOND"])
    2402             :         {
    2403             :                 mark_size *= 1.4; // match volumes
    2404             :                 glVertex3f(x,   y - mark_size,  z);
    2405             :                 glVertex3f(x - mark_size,       y,      z);
    2406             :                 glVertex3f(x - mark_size,       y,      z);
    2407             :                 glVertex3f(x,   y + mark_size,  z);
    2408             :                 glVertex3f(x,   y + mark_size,  z);
    2409             :                 glVertex3f(x + mark_size,       y,      z);
    2410             :                 glVertex3f(x + mark_size,       y,      z);
    2411             :                 glVertex3f(x,   y - mark_size,  z);
    2412             :         }
    2413             :         OOGLEND();
    2414             : }
    2415             : 
    2416             : 
    2417             : - (OOSystemID) targetNextFoundSystem:(int)direction // +1 , 0 , -1
    2418             : {
    2419             :         OOSystemID sys = [PLAYER targetSystemID];
    2420             :         if ([PLAYER guiScreen] != GUI_SCREEN_SHORT_RANGE_CHART && [PLAYER guiScreen] != GUI_SCREEN_LONG_RANGE_CHART) return sys;
    2421             :         
    2422             :         BOOL            *systemsFound = [UNIVERSE systemsFound];
    2423             :         unsigned        i, first = 0, last = 0, count = 0;
    2424             :         int             systemIndex = foundSystem + direction;
    2425             :         
    2426             :         if (direction == 0) systemIndex = 0;
    2427             :         
    2428             :         for (i = 0; i <= kOOMaximumSystemID; i++)
    2429             :         {
    2430             :                 if (systemsFound[i])
    2431             :                 {
    2432             :                         if (count == 0)
    2433             :                         {
    2434             :                                 first = last = i;
    2435             :                         }
    2436             :                         else
    2437             :                         {
    2438             :                                 last = i;
    2439             :                         }
    2440             :                         if (systemIndex == (int)count) 
    2441             :                         {
    2442             :                                 sys = i;
    2443             :                         }
    2444             :                         count++;
    2445             :                 }
    2446             :         }
    2447             :         
    2448             :         if (count == 0) return sys; // empty systemFound list.
    2449             :         
    2450             :         // loop back if needed.
    2451             :         if (systemIndex < 0)
    2452             :         {
    2453             :                 systemIndex = count - 1;
    2454             :                 sys = last;
    2455             :         }
    2456             :         if (systemIndex >= (int)count)
    2457             :         {
    2458             :                 systemIndex = 0;
    2459             :                 sys = first;
    2460             :         }
    2461             :         
    2462             :         foundSystem = systemIndex;
    2463             :         return sys;
    2464             : }
    2465             : 
    2466             : 
    2467             : // Advanced Navigation Array -- galactic chart route mapping - contributed by Nikos Barkas (another_commander).
    2468           0 : - (void) drawAdvancedNavArrayAtX:(float)x y:(float)y z:(float)z alpha:(float)alpha usingRoute:(NSDictionary *) routeInfo optimizedBy:(OORouteType) optimizeBy zoom: (OOScalar) zoom
    2469             : {
    2470             :         GLfloat lr,lg,lb,la,lr2,lg2,lb2,la2;
    2471             :         double                  hscale = size_in_pixels.width / (CHART_WIDTH_AT_MAX_ZOOM*zoom);
    2472             :         double                  vscale = -1.0 * size_in_pixels.height / (2*CHART_HEIGHT_AT_MAX_ZOOM*zoom);
    2473             :         NSPoint                 star = NSZeroPoint, 
    2474             :                 star2 = NSZeroPoint, 
    2475             :                 starabs = NSZeroPoint, 
    2476             :                 star2abs = NSZeroPoint;
    2477             :         OOSystemDescriptionManager *systemManager = [UNIVERSE systemManager];
    2478             :         OOGalaxyID              g = [PLAYER galaxyNumber];
    2479             :         OOSystemID planetNumber = [PLAYER systemID];
    2480             : 
    2481             :         OOColor *defaultConnectionColor = [self colorFromSetting:kGuiChartConnectionColor defaultValue:[OOColor colorWithWhite:0.25 alpha:1.0]];
    2482             :         OOColor *currentJumpColorStart = [self colorFromSetting:kGuiChartCurrentJumpStartColor defaultValue:[OOColor colorWithWhite:0.25 alpha:0.0]];
    2483             :         OOColor *currentJumpColorEnd = [self colorFromSetting:kGuiChartCurrentJumpEndColor defaultValue:[OOColor colorWithWhite:0.25 alpha:0.0]];
    2484             : 
    2485             :         OOColor *thisConnectionColor = nil;
    2486             :         OOColor *thatConnectionColor = nil;
    2487             :         
    2488             :         float jumpRange = MAX_JUMP_RANGE * ((optimizeBy == OPTIMIZED_BY_NONE) ? [PLAYER dialFuel] : 1.0);
    2489             : 
    2490             :         NSInteger concealment[256];
    2491             :         for (NSUInteger i=0;i<256;i++) {
    2492             :                 NSDictionary *systemInfo = [systemManager getPropertiesForSystem:i inGalaxy:g];
    2493             :                 concealment[i] = [systemInfo oo_intForKey:@"concealment" defaultValue:OO_SYSTEMCONCEALMENT_NONE];
    2494             :         }
    2495             : 
    2496             :         
    2497             :         OOGLBEGIN(GL_LINES);
    2498             :         for (OOSystemID i = 0; i < 256; i++)
    2499             :         {
    2500             : 
    2501             :                 if (concealment[i] >= OO_SYSTEMCONCEALMENT_NOTHING) {
    2502             :                         // system is not known
    2503             :                         continue;
    2504             :                 }
    2505             :                 
    2506             :                 /* Concealment */
    2507             :                 if (optimizeBy == OPTIMIZED_BY_NONE && i != planetNumber)
    2508             :                 {
    2509             :                         continue;
    2510             :                 }
    2511             : 
    2512             :                 starabs = [systemManager getCoordinatesForSystem:i inGalaxy:g];
    2513             : 
    2514             :                 star.x = (float)(starabs.x * hscale);
    2515             :                 star.y = (float)(starabs.y * vscale);
    2516             : 
    2517             :                 // if in non-route mode, we're always starting from i, so need
    2518             :                 // to do <i here too.
    2519             :                 OOSystemID loopstart = (optimizeBy == OPTIMIZED_BY_NONE) ? 0 : (i+1);
    2520             : 
    2521             :                 for (OOSystemID j = loopstart; j < 256; j++)
    2522             :                 {
    2523             :                         if (i == j)
    2524             :                         {
    2525             :                                 continue; // for OPTIMIZED_BY_NONE case
    2526             :                         }
    2527             : 
    2528             :                         if (concealment[j] >= OO_SYSTEMCONCEALMENT_NOTHING) {
    2529             :                                 // system is not known
    2530             :                                 continue;
    2531             :                         }
    2532             :                         
    2533             :                         star2abs = [systemManager getCoordinatesForSystem:j inGalaxy:g];
    2534             :                         double d = distanceBetweenPlanetPositions(starabs.x, starabs.y, star2abs.x, star2abs.y);
    2535             :                 
    2536             :                         if (d <= jumpRange)  // another_commander - Default to 7.0 LY.
    2537             :                         {
    2538             :                                 star2.x = (float)(star2abs.x * hscale);
    2539             :                                 star2.y = (float)(star2abs.y * vscale);
    2540             :                                 if (optimizeBy == OPTIMIZED_BY_NONE)
    2541             :                                 {
    2542             :                                         [currentJumpColorStart getRed:&lr green:&lg blue:&lb alpha:&la];
    2543             :                                         [currentJumpColorEnd getRed:&lr2 green:&lg2 blue:&lb2 alpha:&la2];
    2544             :                                         OOGL(glColor4f(lr, lg, lb, la*alpha));
    2545             :                                         glVertex3f(x+star.x, y+star.y, z);
    2546             : 
    2547             :                                         float frac = (d/jumpRange);
    2548             :                                         OOGL(glColor4f(
    2549             :                                                          OOLerp(lr,lr2,frac),
    2550             :                                                          OOLerp(lg,lg2,frac),
    2551             :                                                          OOLerp(lb,lb2,frac),
    2552             :                                                          OOLerp(la,la2,frac)
    2553             :                                                          ));
    2554             :                                         glVertex3f(x+star2.x, y+star2.y, z);
    2555             : 
    2556             :                                 }
    2557             :                                 else
    2558             :                                 {
    2559             :                                         thisConnectionColor = [OOColor colorWithDescription:[systemManager getProperty:@"link_color" forSystemKey:[NSString stringWithFormat:@"interstellar: %d %ld %ld", g, (long)i, (long)j]]];
    2560             :                                 
    2561             :                                         if (thisConnectionColor == nil)
    2562             :                                         {
    2563             :                                                 thisConnectionColor = defaultConnectionColor;
    2564             :                                         }
    2565             :                                         [thisConnectionColor getRed:&lr green:&lg blue:&lb alpha:&la];
    2566             :                                         OOGL(glColor4f(lr, lg, lb, la*alpha));
    2567             : 
    2568             :                                         glVertex3f(x+star.x, y+star.y, z);
    2569             : 
    2570             :                                         // and the other colour for the other end
    2571             :                                         thatConnectionColor = [OOColor colorWithDescription:[systemManager getProperty:@"link_color" forSystemKey:[NSString stringWithFormat:@"interstellar: %d %ld %ld", g, (long)j, (long)i]]];
    2572             :                                 
    2573             :                                         if (thatConnectionColor == nil)
    2574             :                                         {
    2575             :                                                 thatConnectionColor = thisConnectionColor;
    2576             :                                         }
    2577             :                                         [thatConnectionColor getRed:&lr green:&lg blue:&lb alpha:&la];
    2578             :                                         OOGL(glColor4f(lr, lg, lb, la*alpha));
    2579             : 
    2580             :                                         glVertex3f(x+star2.x, y+star2.y, z);
    2581             :                                 }
    2582             :                         }
    2583             :                 }
    2584             :         }
    2585             :         OOGLEND();
    2586             :         
    2587             :         if (optimizeBy == OPTIMIZED_BY_NONE)
    2588             :         {
    2589             :                 return;
    2590             :         }
    2591             : 
    2592             :         if (routeInfo)
    2593             :         {
    2594             :                 NSUInteger i, route_hops = [[routeInfo oo_arrayForKey:@"route"] count] - 1;
    2595             :                 
    2596             :                 if (optimizeBy == OPTIMIZED_BY_JUMPS)
    2597             :                 {
    2598             :                         // route optimised by distance
    2599             :                         [self setGLColorFromSetting:kGuiChartRouteShortColor defaultValue:[OOColor yellowColor] alpha:alpha];
    2600             :                 }
    2601             :                 else
    2602             :                 {
    2603             :                         // route optimised by time
    2604             :                         [self setGLColorFromSetting:kGuiChartRouteQuickColor defaultValue:[OOColor cyanColor] alpha:alpha];
    2605             :                 }
    2606             :                 OOSystemID loc;
    2607             :                 for (i = 0; i < route_hops; i++)
    2608             :                 {
    2609             :                         loc = [[routeInfo objectForKey:@"route"] oo_intAtIndex:i];
    2610             :                         starabs = [systemManager getCoordinatesForSystem:loc inGalaxy:g];
    2611             :                         star2abs = [systemManager getCoordinatesForSystem:[[routeInfo objectForKey:@"route"] oo_intAtIndex:i+1] inGalaxy:g];
    2612             : 
    2613             :                         star.x = (float)(starabs.x * hscale);
    2614             :                         star.y = (float)(starabs.y * vscale);
    2615             :                         
    2616             :                         star2.x = (float)(star2abs.x * hscale);
    2617             :                         star2.y = (float)(star2abs.y * vscale);
    2618             : 
    2619             :                         
    2620             :                         OOGLBEGIN(GL_LINES);
    2621             :                                 glVertex3f(x+star.x, y+star.y, z);
    2622             :                                 glVertex3f(x+star2.x, y+star2.y, z);
    2623             :                         OOGLEND();
    2624             :                         
    2625             :                         // Label the route, if not already labelled
    2626             :                         if (zoom > CHART_ZOOM_SHOW_LABELS && concealment[loc] < OO_SYSTEMCONCEALMENT_NONAME)
    2627             :                         {
    2628             :                                 OODrawString([UNIVERSE systemNameIndex:loc], x + star.x + 2.0, y + star.y, z, NSMakeSize(8,8));
    2629             :                         }
    2630             :                 }
    2631             :                 // Label the destination, which was not included in the above loop.
    2632             :                 if (zoom > CHART_ZOOM_SHOW_LABELS)
    2633             :                 {
    2634             :                         loc = [[routeInfo objectForKey:@"route"] oo_intAtIndex:i];
    2635             :                         if(concealment[loc] < OO_SYSTEMCONCEALMENT_NONAME)
    2636             :                         {
    2637             :                                 OODrawString([UNIVERSE systemNameIndex:loc], x + star2.x + 2.0, y + star2.y, z, NSMakeSize(10,10));
    2638             :                         }
    2639             :                 }
    2640             :         }
    2641             : }
    2642             : 
    2643             : @end

Generated by: LCOV version 1.14