Oolite 1.91.0.7646-241128-10e222e
Loading...
Searching...
No Matches
GuiDisplayGen.m
Go to the documentation of this file.
1/*
2
3GuiDisplayGen.m
4
5Oolite
6Copyright (C) 2004-2013 Giles C Williams and contributors
7
8This program is free software; you can redistribute it and/or
9modify it under the terms of the GNU General Public License
10as published by the Free Software Foundation; either version 2
11of the License, or (at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software
20Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21MA 02110-1301, USA.
22
23*/
24
25#import "GuiDisplayGen.h"
26#import "Universe.h"
27#import "GameController.h"
28#import "PlayerEntity.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"
37#import "OOTexture.h"
41
42OOINLINE 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- (void) drawGLDisplay:(GLfloat)x :(GLfloat)y :(GLfloat)z :(GLfloat) alpha;
50
51- (void) drawCrossHairsWithSize:(GLfloat) size x:(GLfloat)x y:(GLfloat)y z:(GLfloat)z;
52- (void) drawStarChart:(GLfloat)x :(GLfloat)y :(GLfloat)z :(GLfloat) alpha :(BOOL) compact;
53- (void) drawSystemMarkers:(NSArray *)marker atX:(GLfloat)x andY:(GLfloat)y andZ:(GLfloat)z withAlpha:(GLfloat)alpha andScale:(GLfloat)scale;
54- (void) drawSystemMarker:(NSDictionary *)marker atX:(GLfloat)x andY:(GLfloat)y andZ:(GLfloat)z withAlpha:(GLfloat)alpha andScale:(GLfloat)scale;
55
56- (void) drawEquipmentList:(NSArray *)eqptList z:(GLfloat)z;
57- (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
64static 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
988static 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*/
1013static 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 {
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;
1086 bgDescriptor = [UNIVERSE screenTextureDescriptorForKey:@"short_range_chart_mission"];
1087 if (bgDescriptor == nil)
1088 {
1089 bgDescriptor = [UNIVERSE screenTextureDescriptorForKey:@"short_range_chart"];
1090 }
1091 break;
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;
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{
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
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- (void) drawEquipmentList:(NSArray *)eqptList z:(GLfloat)z
1223{
1224 if ([eqptList count] == 0) return;
1225
1227 NSUInteger maxRows = STATUS_EQUIPMENT_MAX_ROWS;
1228 if ([[PLAYER hud] allowBigGui])
1229 {
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
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- (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
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 //
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);
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];
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]));
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();
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 {
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];
1693 }
1694 OODrawStringQuadsAligned(text, x + rowPosition[i].x, y + rowPosition[i].y, z, characterSize,NO);
1695 }
1696 }
1697 }
1698 }
1701}
1702
1703
1704- (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- (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;
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
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
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- (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- (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"];
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- (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
#define MAIN_GUI_PIXEL_ROW_START
#define GUI_KEY_SKIP
#define GUI_MAX_COLUMNS
OOGUIBackgroundSpecial
@ GUI_BACKGROUND_SPECIAL_CUSTOM_ANA_QUICKEST
@ GUI_BACKGROUND_SPECIAL_SHORT_ANA_SHORTEST
@ GUI_BACKGROUND_SPECIAL_LONG
@ GUI_BACKGROUND_SPECIAL_LONG_ANA_SHORTEST
@ GUI_BACKGROUND_SPECIAL_SHORT
@ GUI_BACKGROUND_SPECIAL_NONE
@ GUI_BACKGROUND_SPECIAL_SHORT_ANA_QUICKEST
@ GUI_BACKGROUND_SPECIAL_LONG_ANA_QUICKEST
@ GUI_BACKGROUND_SPECIAL_CUSTOM
@ GUI_BACKGROUND_SPECIAL_CUSTOM_ANA_SHORTEST
OOGUITabStop OOGUITabSettings[GUI_MAX_COLUMNS]
#define MAIN_GUI_PIXEL_WIDTH
#define MAIN_GUI_PIXEL_HEIGHT
#define GUI_DEFAULT_ROWS
#define MAIN_GUI_ROW_HEIGHT
NSInteger OOGUIRow
OOGUIAlignment
@ GUI_ALIGN_RIGHT
@ GUI_ALIGN_LEFT
@ GUI_ALIGN_CENTER
#define GUI_DEFAULT_COLUMNS
static BOOL _refreshStarChart
OOINLINE BOOL RowInRange(OOGUIRow row, NSRange range)
void OODrawHilightedString(NSString *text, GLfloat x, GLfloat y, GLfloat z, NSSize siz)
void OODrawStringQuadsAligned(NSString *text, GLfloat x, GLfloat y, GLfloat z, NSSize siz, BOOL rightAlign)
void OOStartDrawingStrings(void)
NSRect OORectFromString(NSString *text, GLfloat x, GLfloat y, NSSize siz)
void OODrawHilightedPlanetInfo(int gov, int eco, int tec, GLfloat x, GLfloat y, GLfloat z, NSSize siz)
void OODrawString(NSString *text, GLfloat x, GLfloat y, GLfloat z, NSSize siz)
void OODrawPlanetInfo(int gov, int eco, int tec, GLfloat x, GLfloat y, GLfloat z, NSSize siz)
void OOStopDrawingStrings(void)
OOINLINE long long OOClampInteger(long long value, long long minValue, long long maxValue) ALWAYS_INLINE_FUNC
#define EXPECT_NOT(x)
#define OOINLINE
#define EXPECT(x)
#define OOJS_PROFILE_EXIT
#define OOJS_PROFILE_ENTER
void OOJSReportWarning(JSContext *context, NSString *format,...)
NSDictionary * OOJSDictionaryFromJSObject(JSContext *context, JSObject *object)
NSString * OOStringFromJSValue(JSContext *context, jsval value)
OOINLINE JSClass * OOJSGetClass(JSContext *cx, JSObject *obj) ALWAYS_INLINE_FUNC
#define OOLog(class, format,...)
Definition OOLogging.h:88
#define MIN(A, B)
Definition OOMaths.h:111
GLfloat OOScalar
Definition OOMaths.h:64
BOOL OOMouseInteractionModeIsUIScreen(OOMouseInteractionMode mode)
#define OOGLBEGIN
Definition OOOpenGL.h:253
void GLDrawFilledOval(GLfloat x, GLfloat y, GLfloat z, NSSize siz, GLfloat step)
Definition OOOpenGL.m:165
void GLScaledLineWidth(GLfloat width)
Definition OOOpenGL.m:218
void GLDrawOval(GLfloat x, GLfloat y, GLfloat z, NSSize siz, GLfloat step)
Definition OOOpenGL.m:155
#define OOGL(statement)
Definition OOOpenGL.h:251
#define OOGLEND
Definition OOOpenGL.h:254
return self
unsigned count
return nil
float y
float x
#define OOExpandKey(key,...)
NSMutableArray * ScanTokensFromString(NSString *values)
@ OO_SYSTEMCONCEALMENT_NODATA
@ OO_SYSTEMCONCEALMENT_NOTHING
@ OO_SYSTEMCONCEALMENT_NONAME
@ kOOTextureSRGBA
Definition OOTexture.h:63
OOLongRangeChartMode
Definition OOTypes.h:50
OORouteType
Definition OOTypes.h:33
@ OPTIMIZED_BY_NONE
Definition OOTypes.h:34
@ OPTIMIZED_BY_JUMPS
Definition OOTypes.h:35
@ OPTIMIZED_BY_TIME
Definition OOTypes.h:36
int16_t OOSystemID
Definition OOTypes.h:211
uint8_t OOGalaxyID
Definition OOTypes.h:210
double OOTimeDelta
Definition OOTypes.h:224
@ kOOMaximumSystemID
Definition OOTypes.h:217
double OOTimeAbsolute
Definition OOTypes.h:223
#define CHART_SCREEN_VERTICAL_CENTRE
@ STATUS_EQUIPMENT_FIRST_ROW
@ GUI_ROW_CHART_SYSTEM_COMPACT
@ STATUS_EQUIPMENT_MAX_ROWS
@ GUI_ROW_CHART_SYSTEM
@ STATUS_EQUIPMENT_BIGGUI_EXTRA_ROWS
#define CHART_SCREEN_VERTICAL_CENTRE_COMPACT
#define CHART_WIDTH_AT_MAX_ZOOM
#define CHART_ZOOM_SHOW_LABELS
#define CHART_MAX_ZOOM
#define CHART_HEIGHT_AT_MAX_ZOOM
#define PLAYER
#define CHART_CLIP_BORDER
#define MAX_JUMP_RANGE
Definition ShipEntity.h:107
#define UNIVERSE
Definition Universe.h:840
NSMutableArray * rowColor
NSMutableArray * rowText
static OOTexture * TextureForGUITexture(NSDictionary *descriptor)
NSMutableArray * rowKey
OOColor * cyanColor()
Definition OOColor.m:286
OOColor * colorWithRed:green:blue:alpha:(float red,[green] float green,[blue] float blue,[alpha] float alpha)
Definition OOColor.m:95
OOColor * colorWithWhite:alpha:(float white,[alpha] float alpha)
Definition OOColor.m:103
OOColor * orangeColor()
Definition OOColor.m:304
OOColor * colorWithDescription:(id description)
Definition OOColor.m:127
OOColor * redColor()
Definition OOColor.m:268
OOColor * greenColor()
Definition OOColor.m:274
void getRed:green:blue:alpha:(float *red,[green] float *green,[blue] float *blue,[alpha] float *alpha)
Definition OOColor.m:368
OOColor * blueColor()
Definition OOColor.m:280
OOColor * yellowColor()
Definition OOColor.m:292
OOColor * blackColor()
Definition OOColor.m:238
OORGBAComponents rgbaComponents()
Definition OOColor.m:379
NSSize originalDimensions()
Definition OOTexture.m:313
void applyNone()
Definition OOTexture.m:275
id textureWithName:inFolder:options:anisotropy:lodBias:(NSString *name,[inFolder] NSString *directory,[options] OOTextureFlags options,[anisotropy] GLfloat anisotropy,[lodBias] GLfloat lodBias)
Definition OOTexture.m:134
OOLongRangeChartMode longRangeChartMode
OOGalaxyID galaxyNumber()
NSArray * equipmentList()
OORouteType ANAMode()
NSPoint galaxy_coordinates
void stickProfileGraphAxisProfile:screenAt:screenSize:(GLfloat alpha,[screenAt] Vector screenAt,[screenSize] NSSize screenSize)
NSPoint cursor_coordinates
OOScalar chart_zoom
OOSystemID infoSystemID()
NSPoint adjusted_chart_centre()
NSDictionary * markedDestinations()
GLfloat dialFuel()
NSDictionary * dictionaryFromFilesNamed:inFolder:andMerge:(NSString *fileName,[inFolder] NSString *folderName,[andMerge] BOOL mergeFiles)
voidpf void uLong size
Definition ioapi.h:134
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
OOINLINE double distanceBetweenPlanetPositions(int x1, int y1, int x2, int y2) INLINE_CONST_FUNC