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