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