oolite/HeadUpDisplay.m
2005-08-07 17:48:53 +00:00

1971 lines
60 KiB
Objective-C

//
// HeadUpDisplay.m
// Oolite
//
/*
*
* Oolite
*
* Created by Giles Williams on Fri Jul 30 2004.
* Copyright (c) 2004 for aegidian.org. All rights reserved.
*
Copyright (c) 2004, Giles C Williams
All rights reserved.
This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike License.
To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/2.0/
or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
You are free:
• to copy, distribute, display, and perform the work
• to make derivative works
Under the following conditions:
• Attribution. You must give the original author credit.
• Noncommercial. You may not use this work for commercial purposes.
• Share Alike. If you alter, transform, or build upon this work,
you may distribute the resulting work only under a license identical to this one.
For any reuse or distribution, you must make clear to others the license terms of this work.
Any of these conditions can be waived if you get permission from the copyright holder.
Your fair use and other rights are in no way affected by the above.
*/
//
#import "HeadUpDisplay.h"
#import "ResourceManager.h"
#import "OpenGLSprite.h"
#import "PlayerEntity.h"
#import "Universe.h"
#import "TextureStore.h"
@implementation HeadUpDisplay
GLfloat red_color[4] = {1.0, 0.0, 0.0, 1.0};
GLfloat redplus_color[4] = {1.0, 0.0, 0.5, 1.0};
GLfloat yellow_color[4] = {1.0, 1.0, 0.0, 1.0};
GLfloat green_color[4] = {0.0, 1.0, 0.0, 1.0};
float char_widths[128] = {
6.000, 6.000, 6.000, 6.000, 6.000, 6.000, 6.000, 6.000, 6.000, 6.000, 6.000, 6.000, 6.000, 6.000, 6.000, 6.000,
6.000, 6.000, 6.000, 6.000, 6.000, 6.000, 6.000, 6.000, 6.000, 6.000, 6.000, 6.000, 6.000, 6.000, 6.000, 6.000,
1.750, 2.098, 2.987, 3.504, 3.504, 5.602, 4.550, 1.498, 2.098, 2.098, 2.452, 3.679, 1.750, 2.098, 1.750, 1.750,
4.000, 4.000, 4.000, 4.000, 4.000, 4.000, 4.000, 4.000, 4.000, 4.000, 2.098, 2.098, 3.679, 3.679, 3.679, 3.848,
6.143, 4.550, 4.550, 4.550, 4.550, 4.202, 3.848, 4.900, 4.550, 1.750, 3.504, 4.550, 3.848, 5.248, 4.550, 4.900,
4.202, 4.900, 4.550, 4.202, 3.848, 4.550, 4.202, 5.946, 4.202, 4.202, 3.848, 2.098, 1.750, 2.098, 3.679, 3.504,
2.098, 3.504, 3.848, 3.504, 3.848, 3.504, 2.098, 3.848, 3.848, 1.750, 1.750, 3.504, 1.750, 5.602, 3.848, 3.848,
3.848, 3.848, 2.452, 3.504, 2.098, 3.848, 3.504, 4.900, 3.504, 3.504, 3.150, 2.452, 1.763, 2.452, 3.679, 6.000
};
- (id) initWithDictionary:(NSDictionary *) hudinfo;
{
int i;
BOOL areTrumblesToBeDrawn;
self = [super init];
line_width = 1.0;
for (i = 0; i < 360; i++)
sin_value[i] = sin(i * PI / 180); // also used by PlanetEntity, but can't hurt to init it here too!
// int ch;
// NSMutableDictionary *stringAttributes = [NSMutableDictionary dictionaryWithObjectsAndKeys:
// [NSFont fontWithName:@"Helvetica-Bold" size:28], NSFontAttributeName,
// [NSColor blackColor], NSForegroundColorAttributeName, NULL];
// for (ch = 32; ch < 127; ch++)
// {
// unichar uch = (unichar) ch;
// NSString* chr = [NSString stringWithCharacters:&uch length:1];
// NSSize strsize = [chr sizeWithAttributes:stringAttributes];
// if ((ch < 48)||(ch > 57)) // exclude the digits which should be fixed width
// char_widths[ch] = strsize.width * .225;
// }
//
// // output the character sizes for hardcoding
// //
// printf("hard code this:\n\nfloat char_widths[128] = {");
// for (ch = 0; ch < 128; ch++)
// {
// if (!(ch & 15))
// printf("\n");
// printf("\t%.3f", char_widths[ch]);
// if (ch < 127)
// printf(",");
// }
// printf("\n\n");
// // init sprites
#ifndef WIN32
compassSprite = [[OpenGLSprite alloc] initWithImage:[ResourceManager imageNamed:COMPASS_IMAGE inFolder:@"Images"]
cropRectangle:NSMakeRect(0, 0, COMPASS_SIZE, COMPASS_SIZE)
size:NSMakeSize(COMPASS_HALF_SIZE, COMPASS_HALF_SIZE)]; // alloc retains
aegisSprite = [[OpenGLSprite alloc] initWithImage:[ResourceManager imageNamed:AEGIS_IMAGE inFolder:@"Images"]
cropRectangle:NSMakeRect(0, 0, 32, 32)
size:NSMakeSize(32, 32)]; // alloc retains
NSImage *zoomLevelImage = [ResourceManager imageNamed:ZOOM_LEVELS_IMAGE inFolder:@"Images"];
int w1 = [zoomLevelImage size].width / SCANNER_ZOOM_LEVELS;
int h1 = [zoomLevelImage size].height;
for (i = 0; i < SCANNER_ZOOM_LEVELS; i++)
{
zoomLevelSprite[i] = [[OpenGLSprite alloc] initWithImage:zoomLevelImage
cropRectangle:NSMakeRect(w1*i, 0, w1, h1)
size:NSMakeSize(16, 16)]; // alloc retains
}
#else
compassSprite = [[OpenGLSprite alloc] initWithSurface:[ResourceManager surfaceNamed:COMPASS_IMAGE inFolder:@"Images"]
cropRectangle:NSMakeRect(0, 0, COMPASS_SIZE, COMPASS_SIZE)
size:NSMakeSize(COMPASS_HALF_SIZE, COMPASS_HALF_SIZE)]; // alloc retains
aegisSprite = [[OpenGLSprite alloc] initWithSurface:[ResourceManager surfaceNamed:AEGIS_IMAGE inFolder:@"Images"]
cropRectangle:NSMakeRect(0, 0, 32, 32)
size:NSMakeSize(32, 32)]; // alloc retains
SDLImage *zoomLevelImage = [ResourceManager surfaceNamed:ZOOM_LEVELS_IMAGE inFolder:@"Images"];
int w1 = [zoomLevelImage size].width / SCANNER_ZOOM_LEVELS;
int h1 = [zoomLevelImage size].height;
for (i = 0; i < SCANNER_ZOOM_LEVELS; i++)
{
zoomLevelSprite[i] = [[OpenGLSprite alloc] initWithSurface:zoomLevelImage
cropRectangle:NSMakeRect(w1*i, 0, w1, h1)
size:NSMakeSize(16, 16)]; // alloc retains
}
#endif
// init arrays
dialArray = [[NSMutableArray alloc] initWithCapacity:16]; // alloc retains
legendArray = [[NSMutableArray alloc] initWithCapacity:16]; // alloc retains
// populate arrays
if ([hudinfo objectForKey:DIALS_KEY])
{
NSArray *dials = [hudinfo objectForKey:DIALS_KEY];
for (i = 0; i < [dials count]; i++)
{
NSDictionary* dial_info = (NSDictionary *)[dials objectAtIndex:i];
areTrumblesToBeDrawn |= [(NSString*)[dial_info objectForKey:SELECTOR_KEY] isEqual:@"drawTrumbles:"];
[self addDial: dial_info];
}
}
if (!areTrumblesToBeDrawn) // naughty - a hud with no built-in drawTrumbles: - one must be added!
{
NSDictionary* trumble_dial_info = [NSDictionary dictionaryWithObjectsAndKeys: @"drawTrumbles:", SELECTOR_KEY, nil];
[self addDial: trumble_dial_info];
}
if ([hudinfo objectForKey:LEGENDS_KEY])
{
NSArray *legends = [hudinfo objectForKey:LEGENDS_KEY];
for (i = 0; i < [legends count]; i++)
[self addLegend:(NSDictionary *)[legends objectAtIndex:i]];
}
last_transmitter = NO_TARGET;
return self;
}
- (void) dealloc
{
int i;
if (compassSprite) [compassSprite release];
if (aegisSprite) [aegisSprite release];
for (i = 0; i < SCANNER_ZOOM_LEVELS; i++) if (zoomLevelSprite[i]) [zoomLevelSprite[i] release];
if (legendArray) [legendArray release];
if (dialArray) [dialArray release];
[super dealloc];
}
//------------------------------------------------------------------------------------//
GLuint ascii_texture_name;
- (void) setPlayer:(PlayerEntity *) player_entity
{
player = player_entity;
ascii_texture_name = [[[player_entity universe] textureStore] getTextureNameFor:@"asciitext.png"]; // intitalise text texture
}
- (double) scanner_zoom
{
return scanner_zoom;
}
- (void) setScannerZoom:(double) value
{
scanner_zoom = value;
}
- (void) addLegend:(NSDictionary *) info
{
if ([info objectForKey:IMAGE_KEY])
{
//NSLog(@"DEBUG adding Legend %@",[info objectForKey:IMAGE_KEY]);
#ifndef WIN32
NSImage *legendImage = [ResourceManager imageNamed:(NSString *)[info objectForKey:IMAGE_KEY] inFolder:@"Images"];
NSSize imageSize = [legendImage size];
NSSize spriteSize = imageSize;
if ([info objectForKey:WIDTH_KEY])
spriteSize.width = [(NSNumber *)[info objectForKey:WIDTH_KEY] intValue];
if ([info objectForKey:HEIGHT_KEY])
spriteSize.height = [(NSNumber *)[info objectForKey:HEIGHT_KEY] intValue];
OpenGLSprite *legendSprite = [[OpenGLSprite alloc] initWithImage:legendImage
cropRectangle:NSMakeRect(0, 0, imageSize.width, imageSize.height) size:spriteSize]; // retained
#else
SDLImage *legendImage = [ResourceManager surfaceNamed:(NSString *)[info objectForKey:IMAGE_KEY] inFolder:@"Images"];
NSSize imageSize = [legendImage size];
NSSize spriteSize = imageSize;
if ([info objectForKey:WIDTH_KEY])
spriteSize.width = [(NSNumber *)[info objectForKey:WIDTH_KEY] intValue];
if ([info objectForKey:HEIGHT_KEY])
spriteSize.height = [(NSNumber *)[info objectForKey:HEIGHT_KEY] intValue];
OpenGLSprite *legendSprite = [[OpenGLSprite alloc] initWithSurface:legendImage
cropRectangle:NSMakeRect(0, 0, imageSize.width, imageSize.height) size:spriteSize]; // retained
#endif
NSMutableDictionary *legendDict = [NSMutableDictionary dictionaryWithDictionary:info];
[legendDict setObject:legendSprite forKey:SPRITE_KEY];
[legendArray addObject:legendDict];
[legendSprite release];
return;
}
if ([info objectForKey:TEXT_KEY])
{
[legendArray addObject:info];
return;
}
}
- (void) addDial:(NSDictionary *) info
{
if ([info objectForKey:SELECTOR_KEY])
{
//NSLog(@"DEBUG adding Dial for %@",[info objectForKey:SELECTOR_KEY]);
SEL _selector = NSSelectorFromString((NSString *)[info objectForKey:SELECTOR_KEY]);
if ([self respondsToSelector:_selector])
[dialArray addObject:info];
//else
// NSLog(@"DEBUG HeadUpDisplay does not respond to '%@'",[info objectForKey:SELECTOR_KEY]);
}
}
- (void) drawLegends
{
int i;
if (!player)
return;
z1 = [(MyOpenGLView *)[[player universe] gameView] display_z];
for (i = 0; i < [legendArray count]; i++)
[self drawLegend:(NSDictionary *)[legendArray objectAtIndex:i]];
//
checkGLErrors(@"HeadUpDisplay after drawLegends");
//
}
- (void) drawDials
{
int i;
if (!player)
return;
z1 = [(MyOpenGLView *)[[player universe] gameView] display_z];
for (i = 0; i < [dialArray count]; i++)
[self drawHUDItem:(NSDictionary *)[dialArray objectAtIndex:i]];
//
checkGLErrors(@"HeadUpDisplay after drawDials");
//
}
- (void) drawLegend:(NSDictionary *) info
{
if ([info objectForKey:SPRITE_KEY])
{
OpenGLSprite *legendSprite = (OpenGLSprite *)[info objectForKey:SPRITE_KEY];
int x = [(NSNumber *)[info objectForKey:X_KEY] intValue];
int y = [(NSNumber *)[info objectForKey:Y_KEY] intValue];
double alpha = [(NSNumber *)[info objectForKey:ALPHA_KEY] doubleValue];
[legendSprite blitCentredToX:x Y:y Z:z1 Alpha:alpha];
return;
}
if ([info objectForKey:TEXT_KEY])
{
NSString* legendText = (NSString*)[info objectForKey:TEXT_KEY];
NSSize siz = NSMakeSize([(NSNumber *)[info objectForKey:WIDTH_KEY] floatValue],[(NSNumber *)[info objectForKey:HEIGHT_KEY] floatValue]);
double x = [(NSNumber *)[info objectForKey:X_KEY] doubleValue];
double y = [(NSNumber *)[info objectForKey:Y_KEY] doubleValue];
glColor4f( 0.0, 1.0, 0.0, 1.0);
drawString( legendText, x, y, z1, siz);
}
}
- (void) drawHUDItem:(NSDictionary *) info
{
if (([info objectForKey:EQUIPMENT_REQUIRED_KEY])&&
(![player has_extra_equipment:(NSString *)[info objectForKey:EQUIPMENT_REQUIRED_KEY]]))
return;
if ([info objectForKey:SELECTOR_KEY])
{
//NSLog(@"DEBUG about to '%@'",[info objectForKey:SELECTOR_KEY]);
SEL _selector = NSSelectorFromString((NSString *)[info objectForKey:SELECTOR_KEY]);
if ([self respondsToSelector:_selector])
[self performSelector:_selector withObject:info];
else
NSLog(@"DEBUG HeadUpDisplay does not respond to '%@'",[info objectForKey:SELECTOR_KEY]);
}
//
checkGLErrors([NSString stringWithFormat:@"HeadUpDisplay after drawHUDItem %@", info]);
//
}
//---------------------------------------------------------------------//
static BOOL hostiles;
- (void) drawScanner:(NSDictionary *) info
{
GLfloat scanner_color[4] = { 1.0, 0.0, 0.0, 1.0 };
int x = SCANNER_CENTRE_X;
int y = SCANNER_CENTRE_Y;
double alpha = 1.0;
NSSize siz = NSMakeSize( SCANNER_WIDTH, SCANNER_HEIGHT);
//
if ([info objectForKey:X_KEY])
x = [(NSNumber *)[info objectForKey:X_KEY] intValue];
if ([info objectForKey:Y_KEY])
y = [(NSNumber *)[info objectForKey:Y_KEY] intValue];
if ([info objectForKey:ALPHA_KEY])
alpha = [(NSNumber *)[info objectForKey:ALPHA_KEY] doubleValue];
if ([info objectForKey:WIDTH_KEY])
siz.width = [(NSNumber *)[info objectForKey:WIDTH_KEY] floatValue];
if ([info objectForKey:HEIGHT_KEY])
siz.height = [(NSNumber *)[info objectForKey:HEIGHT_KEY] floatValue];
if ([info objectForKey:RGB_COLOR_KEY])
{
NSArray* rgb_array = (NSArray*)[info objectForKey:RGB_COLOR_KEY];
scanner_color[0] = (GLfloat)[(NSNumber *)[rgb_array objectAtIndex:0] floatValue];
scanner_color[1] = (GLfloat)[(NSNumber *)[rgb_array objectAtIndex:1] floatValue];
scanner_color[2] = (GLfloat)[(NSNumber *)[rgb_array objectAtIndex:2] floatValue];
}
scanner_color[3] = (GLfloat)alpha;
double z_factor = siz.height / siz.width; // approx 1/4
double y_factor = 1.0 - sqrt(z_factor); // approx 1/2
// NSLog(@"DEBUG z_factor %.2f y_factor %.2f", z_factor, y_factor);
int i;
int scanner_cx = x;
int scanner_cy = y;
double mass_lock_range2 = 25600.0*25600.0;
int scanner_scale = SCANNER_MAX_RANGE * 2.5 / siz.width;
double max_scanner_range2 = SCANNER_SCALE*SCANNER_SCALE*10000.0/(scanner_zoom*scanner_zoom);
BOOL isHostile = NO;
BOOL foundHostiles = NO;
BOOL mass_locked = NO;
Vector position, relativePosition;
Matrix rotMatrix;
int flash = ((int)([[player universe] getTime] * 4))&1;
//
// use a non-mutable copy so this can't be changed under us.
//
Universe* uni = [player universe];
int ent_count = uni->n_entities;
Entity** uni_entities = uni->sortedEntities; // grab the public sorted list
Entity* my_entities[ent_count];
for (i = 0; i < ent_count; i++)
my_entities[i] = [uni_entities[i] retain]; // retained
//
Entity *drawthing = nil;
//
GLfloat col[4] = { 1.0, 1.0, 1.0, 1.0}; // can be manipulated
position = player->position;
gl_matrix_into_matrix([player rotationMatrix], rotMatrix);
// NSLog(@"drawing grid size %.1f x %.1f", siz.width, siz.height);
glColor4fv( scanner_color);
drawScannerGrid( x, y, z1, siz, [[player universe] viewDir], line_width);
GLfloat off_scope2 = (siz.width > siz.height) ? siz.width * siz.width : siz.height * siz.height;
//
if ([[player universe] viewDir] != VIEW_DOCKED)
{
double upscale = scanner_zoom*1.25/scanner_scale;
off_scope2 /= upscale * upscale;
double max_blip = 0.0;
for (i = 0; i < ent_count; i++) // scanner lollypops
{
drawthing = my_entities[i];
int drawClass = drawthing->scan_class;
if (drawClass == CLASS_PLAYER) drawClass = CLASS_NO_DRAW;
// consider large bodies for mass_lock
if (drawthing->isPlanet)
{
PlanetEntity* planet = (PlanetEntity *)drawthing;
double dist = planet->zero_distance;
double rad = planet->collision_radius;
double factor = ([planet getPlanetType] == PLANET_TYPE_SUN) ? 2.0 : 4.0;
if (dist < rad*rad*factor)
{
mass_locked = YES;
}
}
if (drawClass != CLASS_NO_DRAW)
{
GLfloat x1,y1,y2;
float ms_blip = 0.0;
if (drawthing->zero_distance <= mass_lock_range2)
{
switch (drawClass)
{
case CLASS_BUOY :
case CLASS_ROCK :
case CLASS_CARGO :
case CLASS_MINE :
break;
case CLASS_THARGOID :
case CLASS_MISSILE :
case CLASS_STATION :
case CLASS_POLICE :
case CLASS_MILITARY :
default :
mass_locked = YES;
break;
}
}
[player setAlert_flag:ALERT_FLAG_MASS_LOCK :mass_locked];
if ((isnan(drawthing->zero_distance))||(drawthing->zero_distance > max_scanner_range2))
continue;
// has it sent a recent message
//
if (drawthing->isShip)
ms_blip = 2.0 * [(ShipEntity *)drawthing message_time];
if (ms_blip > max_blip)
{
max_blip = ms_blip;
last_transmitter = [drawthing universal_id];
}
ms_blip -= floor(ms_blip);
relativePosition = [drawthing relative_position];
// rotate the view
mult_vector(&relativePosition, rotMatrix);
// scale the view
relativePosition.x *= upscale; relativePosition.y *= upscale; relativePosition.z *= upscale;
x1 = relativePosition.x;
y1 = z_factor * relativePosition.z;
y2 = y1 + y_factor * relativePosition.y;
isHostile = NO;
if (drawthing->isShip)
{
ShipEntity* ship = (ShipEntity *)drawthing;
double wr = [ship weapon_range];
isHostile = (([ship hasHostileTarget])&&([ship getPrimaryTarget] == player)&&(drawthing->zero_distance < wr*wr));
GLfloat* base_col = [ship scannerDisplayColorForShip:player :isHostile :flash];
col[0] = base_col[0]; col[1] = base_col[1]; col[2] = base_col[2]; col[3] = alpha * base_col[3];
}
// position the scanner
x1 += scanner_cx; y1 += scanner_cy; y2 += scanner_cy;
switch (drawClass)
{
case CLASS_THARGOID :
foundHostiles = YES;
break;
case CLASS_ROCK :
case CLASS_CARGO :
case CLASS_MISSILE :
case CLASS_STATION :
case CLASS_BUOY :
case CLASS_POLICE :
case CLASS_MILITARY :
case CLASS_MINE :
default :
if (isHostile)
foundHostiles = YES;
break;
}
if (ms_blip > 0.0)
{
drawSpecialOval( x1 - 0.5, y2 + 1.5, z1, NSMakeSize(16.0 * (1.0 - ms_blip), 8.0 * (1.0 - ms_blip)), 30, col);
}
if ((drawthing->isParticle)&&(drawClass == CLASS_MINE))
{
double r1 = 2.5 + drawthing->collision_radius * upscale;
double l2 = r1*r1 - relativePosition.y*relativePosition.y;
double r0 = (l2 > 0)? sqrt(l2): 0;
if (r0 > 0)
{
glColor4f( 1.0, 0.5, 1.0, alpha);
drawOval( x1 - 0.5, y1 + 1.5, z1, NSMakeSize( r0, r0 * siz.height / siz.width), 20);
}
glColor4f( 0.5, 0.0, 1.0, 0.33333 * alpha);
drawFilledOval( x1 - 0.5, y2 + 1.5, z1, NSMakeSize( r1, r1), 15);
}
else
{
glBegin(GL_QUADS);
glColor4fv(col);
glVertex3f( x1-3, y2, z1); glVertex3f( x1+2, y2, z1); glVertex3f( x1+2, y2+3, z1); glVertex3f( x1-3, y2+3, z1);
col[3] *= 0.3333; // one third the alpha
glColor4fv(col);
glVertex3f( x1, y1, z1); glVertex3f( x1+2, y1, z1); glVertex3f( x1+2, y2, z1); glVertex3f( x1, y2, z1);
glEnd();
}
}
}
//
[player setAlert_flag:ALERT_FLAG_HOSTILES :foundHostiles];
//
if ((foundHostiles)&&(!hostiles))
{
hostiles = YES;
}
if ((!foundHostiles)&&(hostiles))
{
hostiles = NO; // there are now no hostiles on scope, relax
}
}
//
for (i = 0; i < ent_count; i++)
[my_entities[i] release]; // released
}
- (void) refreshLastTransmitter
{
Entity* lt = [[player universe] entityForUniversalID:last_transmitter];
if ((lt == nil)||(!(lt->isShip)))
return;
ShipEntity* st = (ShipEntity*)lt;
// NSLog(@"DEBUG Last Transmitter (%d) == %@ %d", last_transmitter, [st name], [st universal_id]);
if ([st message_time] <= 0.0)
[st setMessage_time:2.5];
}
- (void) drawScannerZoomIndicator:(NSDictionary *) info
{
int x = ZOOM_INDICATOR_CENTRE_X;
int y = ZOOM_INDICATOR_CENTRE_Y;
double alpha = 1.0;
if ([info objectForKey:X_KEY])
x = [(NSNumber *)[info objectForKey:X_KEY] intValue];
if ([info objectForKey:Y_KEY])
y = [(NSNumber *)[info objectForKey:Y_KEY] intValue];
if ([info objectForKey:ALPHA_KEY])
alpha = [(NSNumber *)[info objectForKey:ALPHA_KEY] doubleValue];
int zoom_indicator_cx = x;
int zoom_indicator_cy = y;
int zl = scanner_zoom - 1.0;
if (zl < 0) zl = 0;
if (zl >= SCANNER_ZOOM_LEVELS) zl = SCANNER_ZOOM_LEVELS - 1;
[zoomLevelSprite[zl] blitCentredToX:zoom_indicator_cx Y:zoom_indicator_cy Z:z1 Alpha:(zl == 0) ? 0.75 * alpha : alpha]; // vary alpha up if zoomed
}
- (void) drawCompass:(NSDictionary *) info
{
int x = COMPASS_CENTRE_X;
int y = COMPASS_CENTRE_Y;
double alpha = 1.0;
if ([info objectForKey:X_KEY])
x = [(NSNumber *)[info objectForKey:X_KEY] intValue];
if ([info objectForKey:Y_KEY])
y = [(NSNumber *)[info objectForKey:Y_KEY] intValue];
if ([info objectForKey:ALPHA_KEY])
alpha = [(NSNumber *)[info objectForKey:ALPHA_KEY] doubleValue];
// draw the compass
Matrix rotMatrix;
Vector position = player->position;
gl_matrix_into_matrix([player rotationMatrix], rotMatrix);
//
[compassSprite blitCentredToX:x Y:y Z:z1 Alpha:alpha];
//
PlanetEntity* the_sun = [[player universe] sun];
PlanetEntity* the_planet = [[player universe] planet];
StationEntity* the_station = [[player universe] station];
Entity* the_target = [player getPrimaryTarget];
Entity* the_next_beacon = [[player universe] entityForUniversalID:[player nextBeaconID]];
if (([[player universe] viewDir] != VIEW_DOCKED)&&(the_sun)&&(the_planet))
{
Vector relativePosition;
if ([player compass_mode] == COMPASS_MODE_BASIC)
{
relativePosition = the_planet->position;
if (([player checkForAegis] != AEGIS_NONE)&&(the_station))
relativePosition = the_station->position;
}
else
{
switch ([player compass_mode])
{
case COMPASS_MODE_PLANET:
relativePosition = the_planet->position;
break;
case COMPASS_MODE_STATION:
relativePosition = the_station->position;
break;
case COMPASS_MODE_SUN:
relativePosition = the_sun->position;
break;
case COMPASS_MODE_TARGET:
if (the_target)
relativePosition = the_target->position;
else
{
[player setCompass_mode:COMPASS_MODE_PLANET];
relativePosition = the_planet->position;
}
break;
case COMPASS_MODE_BEACONS:
if (the_next_beacon)
relativePosition = the_next_beacon->position;
else
{
[player setCompass_mode:COMPASS_MODE_PLANET];
relativePosition = the_planet->position;
}
break;
}
}
// translate the view
relativePosition.x -= position.x; relativePosition.y -= position.y; relativePosition.z -= position.z;
// rotate the view
mult_vector(&relativePosition, rotMatrix);
if (relativePosition.x||relativePosition.y||relativePosition.z)
relativePosition = unit_vector(&relativePosition);
else
relativePosition.z = 1.0;
relativePosition = unit_vector(&relativePosition);
relativePosition.x *= [compassSprite size].width * 0.4;
relativePosition.y *= [compassSprite size].height * 0.4;
relativePosition.x += x;
relativePosition.y += y;
if ([player compass_mode] == COMPASS_MODE_BASIC)
{
NSSize oldblipsize = NSMakeSize( 6, 6);
// [self drawCompassPlanetBlipAt:relativePosition Alpha:alpha];
[self drawCompassPlanetBlipAt:relativePosition Size:oldblipsize Alpha:alpha];
}
else
{
NSSize sz = [compassSprite size];
sz.width *= 0.2;
sz.height *= 0.2;
glLineWidth(2.0);
switch ([player compass_mode])
{
case COMPASS_MODE_PLANET:
[self drawCompassPlanetBlipAt:relativePosition Size:sz Alpha:alpha];
break;
case COMPASS_MODE_STATION:
[self drawCompassStationBlipAt:relativePosition Size:sz Alpha:alpha];
break;
case COMPASS_MODE_SUN:
[self drawCompassSunBlipAt:relativePosition Size:sz Alpha:alpha];
break;
case COMPASS_MODE_TARGET:
[self drawCompassTargetBlipAt:relativePosition Size:sz Alpha:alpha];
break;
case COMPASS_MODE_BEACONS:
[self drawCompassBeaconBlipAt:relativePosition Size:sz Alpha:alpha];
drawString( [NSString stringWithFormat:@"%c", [(ShipEntity*)the_next_beacon beaconChar]],
x - 2.5 * sz.width, y - 3.0 * sz.height, z1, NSMakeSize(sz.width * 2, sz.height * 2));
break;
}
}
}
}
- (void) drawCompassPlanetBlipAt:(Vector) relativePosition Size:(NSSize) siz Alpha:(GLfloat) alpha
{
if (relativePosition.z >= 0)
{
glColor4f(0.0,1.0,0.0,0.75 * alpha);
drawFilledOval( relativePosition.x, relativePosition.y, z1, siz, 30);
glColor4f(0.0,1.0,0.0,alpha);
drawOval( relativePosition.x, relativePosition.y, z1, siz, 30);
}
else
{
glColor4f(1.0,0.0,0.0,alpha);
drawOval( relativePosition.x, relativePosition.y, z1, siz, 30);
}
}
- (void) drawCompassStationBlipAt:(Vector) relativePosition Size:(NSSize) siz Alpha:(GLfloat) alpha
{
if (relativePosition.z >= 0)
{
glColor4f(0.0,1.0,0.0,alpha);
}
else
{
glColor4f(1.0,0.0,0.0,alpha);
}
glBegin(GL_LINE_LOOP);
glVertex3f(relativePosition.x - 0.5 * siz.width, relativePosition.y - 0.5 * siz.height, z1);
glVertex3f(relativePosition.x + 0.5 * siz.width, relativePosition.y - 0.5 * siz.height, z1);
glVertex3f(relativePosition.x + 0.5 * siz.width, relativePosition.y + 0.5 * siz.height, z1);
glVertex3f(relativePosition.x - 0.5 * siz.width, relativePosition.y + 0.5 * siz.height, z1);
glEnd();
}
- (void) drawCompassSunBlipAt:(Vector) relativePosition Size:(NSSize) siz Alpha:(GLfloat) alpha
{
glColor4f(1.0,1.0,0.0,0.75 * alpha);
drawFilledOval( relativePosition.x, relativePosition.y, z1, siz, 30);
if (relativePosition.z >= 0)
{
glColor4f(0.0,1.0,0.0,alpha);
drawOval( relativePosition.x, relativePosition.y, z1, siz, 30);
}
else
{
glColor4f(1.0,0.0,0.0,alpha);
drawOval( relativePosition.x, relativePosition.y, z1, siz, 30);
}
}
- (void) drawCompassTargetBlipAt:(Vector) relativePosition Size:(NSSize) siz Alpha:(GLfloat) alpha
{
if (relativePosition.z >= 0)
{
glColor4f(0.0,1.0,0.0,alpha);
}
else
{
glColor4f(1.0,0.0,0.0,alpha);
}
glBegin(GL_LINES);
glVertex3f(relativePosition.x - siz.width, relativePosition.y, z1);
glVertex3f(relativePosition.x + siz.width, relativePosition.y, z1);
glVertex3f(relativePosition.x, relativePosition.y - siz.height, z1);
glVertex3f(relativePosition.x, relativePosition.y + siz.height, z1);
glEnd();
drawOval( relativePosition.x, relativePosition.y, z1, siz, 30);
}
- (void) drawCompassWitchpointBlipAt:(Vector) relativePosition Size:(NSSize) siz Alpha:(GLfloat) alpha
{
if (relativePosition.z >= 0)
{
glColor4f(0.0,1.0,0.0,alpha);
}
else
{
glColor4f(1.0,0.0,0.0,alpha);
}
glBegin(GL_LINES);
glVertex3f(relativePosition.x - 0.5 * siz.width, relativePosition.y + 0.5 * siz.height, z1);
glVertex3f(relativePosition.x - 0.25 * siz.width, relativePosition.y - 0.5 * siz.height, z1);
glVertex3f(relativePosition.x - 0.25 * siz.width, relativePosition.y - 0.5 * siz.height, z1);
glVertex3f(relativePosition.x, relativePosition.y, z1);
glVertex3f(relativePosition.x, relativePosition.y, z1);
glVertex3f(relativePosition.x + 0.25 * siz.width, relativePosition.y - 0.5 * siz.height, z1);
glVertex3f(relativePosition.x + 0.25 * siz.width, relativePosition.y - 0.5 * siz.height, z1);
glVertex3f(relativePosition.x + 0.5 * siz.width, relativePosition.y + 0.5 * siz.height, z1);
glEnd();
}
- (void) drawCompassBeaconBlipAt:(Vector) relativePosition Size:(NSSize) siz Alpha:(GLfloat) alpha
{
if (relativePosition.z >= 0)
{
glColor4f(0.0,1.0,0.0,alpha);
}
else
{
glColor4f(1.0,0.0,0.0,alpha);
}
glBegin(GL_LINES);
glVertex3f(relativePosition.x - 0.5 * siz.width, relativePosition.y - 0.5 * siz.height, z1);
glVertex3f(relativePosition.x, relativePosition.y + 0.5 * siz.height, z1);
glVertex3f(relativePosition.x + 0.5 * siz.width, relativePosition.y - 0.5 * siz.height, z1);
glVertex3f(relativePosition.x, relativePosition.y + 0.5 * siz.height, z1);
glVertex3f(relativePosition.x - 0.5 * siz.width, relativePosition.y - 0.5 * siz.height, z1);
glVertex3f(relativePosition.x + 0.5 * siz.width, relativePosition.y - 0.5 * siz.height, z1);
glEnd();
}
- (void) drawAegis:(NSDictionary *) info
{
int x = AEGIS_CENTRE_X;
int y = AEGIS_CENTRE_Y;
double alpha = 1.0;
if ([info objectForKey:X_KEY])
x = [(NSNumber *)[info objectForKey:X_KEY] intValue];
if ([info objectForKey:Y_KEY])
y = [(NSNumber *)[info objectForKey:Y_KEY] intValue];
if ([info objectForKey:ALPHA_KEY])
alpha = [(NSNumber *)[info objectForKey:ALPHA_KEY] doubleValue];
// draw the aegis indicator
//
if (([[player universe] viewDir] != VIEW_DOCKED)&&([[player universe] sun])&&([player checkForAegis] == AEGIS_IN_DOCKING_RANGE))
[aegisSprite blitCentredToX:x Y:y Z:z1 Alpha:alpha];
}
- (void) drawSpeedBar:(NSDictionary *) info
{
double ds = [player dial_speed];
// double hs = [player dial_hyper_speed];
int x = SPEED_BAR_CENTRE_X;
int y = SPEED_BAR_CENTRE_Y;
NSSize siz = NSMakeSize( SPEED_BAR_WIDTH, SPEED_BAR_HEIGHT);
if ([info objectForKey:X_KEY])
x = [(NSNumber *)[info objectForKey:X_KEY] intValue];
if ([info objectForKey:Y_KEY])
y = [(NSNumber *)[info objectForKey:Y_KEY] intValue];
if ([info objectForKey:WIDTH_KEY])
siz.width = [(NSNumber *)[info objectForKey:WIDTH_KEY] intValue];
if ([info objectForKey:HEIGHT_KEY])
siz.height = [(NSNumber *)[info objectForKey:HEIGHT_KEY] intValue];
BOOL draw_surround = SPEED_BAR_DRAW_SURROUND;
if ([info objectForKey:DRAW_SURROUND_KEY])
draw_surround = [(NSNumber *)[info objectForKey:DRAW_SURROUND_KEY] boolValue];
if (draw_surround)
{
// draw speed surround
glColor4fv(green_color);
hudDrawSurroundAt( x, y, z1, siz);
}
// draw speed bar
if (ds > .25)
glColor4fv(yellow_color);
if (ds > .80)
glColor4fv(red_color);
hudDrawBarAt( x, y, z1, siz, ds);
}
- (void) drawRollBar:(NSDictionary *) info
{
int x = ROLL_BAR_CENTRE_X;
int y = ROLL_BAR_CENTRE_Y;
NSSize siz = NSMakeSize( ROLL_BAR_WIDTH, ROLL_BAR_HEIGHT);
if ([info objectForKey:X_KEY])
x = [(NSNumber *)[info objectForKey:X_KEY] intValue];
if ([info objectForKey:Y_KEY])
y = [(NSNumber *)[info objectForKey:Y_KEY] intValue];
if ([info objectForKey:WIDTH_KEY])
siz.width = [(NSNumber *)[info objectForKey:WIDTH_KEY] intValue];
if ([info objectForKey:HEIGHT_KEY])
siz.height = [(NSNumber *)[info objectForKey:HEIGHT_KEY] intValue];
BOOL draw_surround = ROLL_BAR_DRAW_SURROUND;
if ([info objectForKey:DRAW_SURROUND_KEY])
draw_surround = [(NSNumber *)[info objectForKey:DRAW_SURROUND_KEY] boolValue];
if (draw_surround)
{
// draw ROLL surround
glColor4fv(green_color);
hudDrawSurroundAt( x, y, z1, siz);
}
// draw ROLL bar
glColor4fv(yellow_color);
hudDrawIndicatorAt( x, y, z1, siz, [player dial_roll]);
}
- (void) drawPitchBar:(NSDictionary *) info
{
int x = PITCH_BAR_CENTRE_X;
int y = PITCH_BAR_CENTRE_Y;
NSSize siz = NSMakeSize( PITCH_BAR_WIDTH, PITCH_BAR_HEIGHT);
if ([info objectForKey:X_KEY])
x = [(NSNumber *)[info objectForKey:X_KEY] intValue];
if ([info objectForKey:Y_KEY])
y = [(NSNumber *)[info objectForKey:Y_KEY] intValue];
if ([info objectForKey:WIDTH_KEY])
siz.width = [(NSNumber *)[info objectForKey:WIDTH_KEY] intValue];
if ([info objectForKey:HEIGHT_KEY])
siz.height = [(NSNumber *)[info objectForKey:HEIGHT_KEY] intValue];
BOOL draw_surround = PITCH_BAR_DRAW_SURROUND;
if ([info objectForKey:DRAW_SURROUND_KEY])
draw_surround = [(NSNumber *)[info objectForKey:DRAW_SURROUND_KEY] boolValue];
if (draw_surround)
{
// draw PITCH surround
glColor4fv(green_color);
hudDrawSurroundAt( x, y, z1, siz);
}
// draw PITCH bar
glColor4fv(yellow_color);
hudDrawIndicatorAt( x, y, z1, siz, [player dial_pitch]);
}
- (void) drawEnergyGauge:(NSDictionary *) info
{
int n_bars = [player dial_max_energy]/64.0;
if (n_bars < 1)
n_bars = 1;
int x = ENERGY_GAUGE_CENTRE_X;
int y = ENERGY_GAUGE_CENTRE_Y;
NSSize siz = NSMakeSize( ENERGY_GAUGE_WIDTH, ENERGY_GAUGE_HEIGHT);
if ([info objectForKey:X_KEY])
x = [(NSNumber *)[info objectForKey:X_KEY] intValue];
if ([info objectForKey:Y_KEY])
y = [(NSNumber *)[info objectForKey:Y_KEY] intValue];
if ([info objectForKey:WIDTH_KEY])
siz.width = [(NSNumber *)[info objectForKey:WIDTH_KEY] intValue];
if ([info objectForKey:HEIGHT_KEY])
siz.height = [(NSNumber *)[info objectForKey:HEIGHT_KEY] intValue];
BOOL draw_surround = ENERGY_GAUGE_DRAW_SURROUND;
if ([info objectForKey:DRAW_SURROUND_KEY])
draw_surround = [(NSNumber *)[info objectForKey:DRAW_SURROUND_KEY] boolValue];
BOOL labelled = YES;
if ([info objectForKey:LABELLED_KEY])
labelled = [(NSNumber *)[info objectForKey:LABELLED_KEY] boolValue];
if ([info objectForKey:N_BARS_KEY])
n_bars = [(NSNumber *)[info objectForKey:N_BARS_KEY] intValue];
if (n_bars > 8)
labelled = NO;
if (draw_surround)
{
// draw energy surround
glColor4fv(yellow_color);
hudDrawSurroundAt( x, y, z1, siz);
}
// draw energy banks
{
int qy = siz.height / n_bars;
NSSize dial_size = NSMakeSize(siz.width,qy - 2);
int cy = y - (n_bars - 1) * qy / 2;
double energy = [player dial_energy]*n_bars;
[player setAlert_flag:ALERT_FLAG_ENERGY :((energy < 1.0)&&(player->status == STATUS_IN_FLIGHT))];
int i;
for (i = 0; i < n_bars; i++)
{
glColor4fv(yellow_color);
if (energy > 1.0)
hudDrawBarAt( x, cy, z1, dial_size, 1.0);
if ((energy > 0.0)&&(energy <= 1.0))
hudDrawBarAt( x, cy, z1, dial_size, energy);
if (labelled)
{
glColor4f( 0.0, 1.0, 0.0, 1.0);
drawString([NSString stringWithFormat:@"E%x",n_bars - i], x + 0.5 * dial_size.width + 2, cy - 0.5 * qy, z1, NSMakeSize(9, (qy < 18)? qy : 18 ));
}
energy -= 1.0;
cy += qy;
}
}
}
- (void) drawForwardShieldBar:(NSDictionary *) info
{
int x = FORWARD_SHIELD_BAR_CENTRE_X;
int y = FORWARD_SHIELD_BAR_CENTRE_Y;
NSSize siz = NSMakeSize( FORWARD_SHIELD_BAR_WIDTH, FORWARD_SHIELD_BAR_HEIGHT);
if ([info objectForKey:X_KEY])
x = [(NSNumber *)[info objectForKey:X_KEY] intValue];
if ([info objectForKey:Y_KEY])
y = [(NSNumber *)[info objectForKey:Y_KEY] intValue];
if ([info objectForKey:WIDTH_KEY])
siz.width = [(NSNumber *)[info objectForKey:WIDTH_KEY] intValue];
if ([info objectForKey:HEIGHT_KEY])
siz.height = [(NSNumber *)[info objectForKey:HEIGHT_KEY] intValue];
BOOL draw_surround = FORWARD_SHIELD_BAR_DRAW_SURROUND;
if ([info objectForKey:DRAW_SURROUND_KEY])
draw_surround = [(NSNumber *)[info objectForKey:DRAW_SURROUND_KEY] boolValue];
double shield = [player dial_forward_shield];
if (draw_surround)
{
// draw forward_shield surround
glColor4fv(green_color);
hudDrawSurroundAt( x, y, z1, siz);
}
// draw forward_shield bar
glColor4fv(green_color);
if (shield < .80)
glColor4fv(yellow_color);
if (shield < .25)
glColor4fv(red_color);
hudDrawBarAt( x, y, z1, siz, shield);
}
- (void) drawAftShieldBar:(NSDictionary *) info
{
int x = AFT_SHIELD_BAR_CENTRE_X;
int y = AFT_SHIELD_BAR_CENTRE_Y;
NSSize siz = NSMakeSize( AFT_SHIELD_BAR_WIDTH, AFT_SHIELD_BAR_HEIGHT);
if ([info objectForKey:X_KEY])
x = [(NSNumber *)[info objectForKey:X_KEY] intValue];
if ([info objectForKey:Y_KEY])
y = [(NSNumber *)[info objectForKey:Y_KEY] intValue];
if ([info objectForKey:WIDTH_KEY])
siz.width = [(NSNumber *)[info objectForKey:WIDTH_KEY] intValue];
if ([info objectForKey:HEIGHT_KEY])
siz.height = [(NSNumber *)[info objectForKey:HEIGHT_KEY] intValue];
BOOL draw_surround = AFT_SHIELD_BAR_DRAW_SURROUND;
if ([info objectForKey:DRAW_SURROUND_KEY])
draw_surround = [(NSNumber *)[info objectForKey:DRAW_SURROUND_KEY] boolValue];
double shield = [player dial_aft_shield];
if (draw_surround)
{
// draw aft_shield surround
glColor4fv(green_color);
hudDrawSurroundAt( x, y, z1, siz);
}
// draw aft_shield bar
glColor4fv(green_color);
if (shield < .80)
glColor4fv(yellow_color);
if (shield < .25)
glColor4fv(red_color);
hudDrawBarAt( x, y, z1, siz, shield);
}
- (void) drawFuelBar:(NSDictionary *) info
{
int x = FUEL_BAR_CENTRE_X;
int y = FUEL_BAR_CENTRE_Y;
NSSize siz = NSMakeSize( FUEL_BAR_WIDTH, FUEL_BAR_HEIGHT);
if ([info objectForKey:X_KEY])
x = [(NSNumber *)[info objectForKey:X_KEY] intValue];
if ([info objectForKey:Y_KEY])
y = [(NSNumber *)[info objectForKey:Y_KEY] intValue];
if ([info objectForKey:WIDTH_KEY])
siz.width = [(NSNumber *)[info objectForKey:WIDTH_KEY] intValue];
if ([info objectForKey:HEIGHT_KEY])
siz.height = [(NSNumber *)[info objectForKey:HEIGHT_KEY] intValue];
// draw fuel bar
glColor4fv(yellow_color);
hudDrawBarAt( x, y, z1, siz, [player dial_fuel]);
}
- (void) drawCabinTempBar:(NSDictionary *) info
{
int x = CABIN_TEMP_BAR_CENTRE_X;
int y = CABIN_TEMP_BAR_CENTRE_Y;
NSSize siz = NSMakeSize( CABIN_TEMP_BAR_WIDTH, CABIN_TEMP_BAR_HEIGHT);
if ([info objectForKey:X_KEY])
x = [(NSNumber *)[info objectForKey:X_KEY] intValue];
if ([info objectForKey:Y_KEY])
y = [(NSNumber *)[info objectForKey:Y_KEY] intValue];
if ([info objectForKey:WIDTH_KEY])
siz.width = [(NSNumber *)[info objectForKey:WIDTH_KEY] intValue];
if ([info objectForKey:HEIGHT_KEY])
siz.height = [(NSNumber *)[info objectForKey:HEIGHT_KEY] intValue];
double temp = [player dial_cabin_temp];
int flash = (int)([[player universe] getTime] * 4);
flash &= 1;
// draw cabin_temp bar
glColor4fv(green_color);
if (temp > .25)
glColor4fv(yellow_color);
if (temp > .80)
glColor4fv(red_color);
if ((flash)&&(temp > .90))
glColor4fv(redplus_color);
[player setAlert_flag:ALERT_FLAG_TEMP :((temp > .90)&&(player->status == STATUS_IN_FLIGHT))];
hudDrawBarAt( x, y, z1, siz, temp);
}
- (void) drawWeaponTempBar:(NSDictionary *) info
{
int x = WEAPON_TEMP_BAR_CENTRE_X;
int y = WEAPON_TEMP_BAR_CENTRE_Y;
NSSize siz = NSMakeSize( WEAPON_TEMP_BAR_WIDTH, WEAPON_TEMP_BAR_HEIGHT);
if ([info objectForKey:X_KEY])
x = [(NSNumber *)[info objectForKey:X_KEY] intValue];
if ([info objectForKey:Y_KEY])
y = [(NSNumber *)[info objectForKey:Y_KEY] intValue];
if ([info objectForKey:WIDTH_KEY])
siz.width = [(NSNumber *)[info objectForKey:WIDTH_KEY] intValue];
if ([info objectForKey:HEIGHT_KEY])
siz.height = [(NSNumber *)[info objectForKey:HEIGHT_KEY] intValue];
double temp = [player dial_weapon_temp];
// draw weapon_temp bar
glColor4fv(green_color);
if (temp > .25)
glColor4fv(yellow_color);
if (temp > .80)
glColor4fv(red_color);
hudDrawBarAt( x, y, z1, siz, temp);
}
- (void) drawAltitudeBar:(NSDictionary *) info
{
int x = ALTITUDE_BAR_CENTRE_X;
int y = ALTITUDE_BAR_CENTRE_Y;
NSSize siz = NSMakeSize( ALTITUDE_BAR_WIDTH, ALTITUDE_BAR_HEIGHT);
if ([info objectForKey:X_KEY])
x = [(NSNumber *)[info objectForKey:X_KEY] intValue];
if ([info objectForKey:Y_KEY])
y = [(NSNumber *)[info objectForKey:Y_KEY] intValue];
if ([info objectForKey:WIDTH_KEY])
siz.width = [(NSNumber *)[info objectForKey:WIDTH_KEY] intValue];
if ([info objectForKey:HEIGHT_KEY])
siz.height = [(NSNumber *)[info objectForKey:HEIGHT_KEY] intValue];
double alt = [player dial_altitude];
int flash = (int)([[player universe] getTime] * 4);
flash &= 1;
// draw altitude bar
glColor4fv(green_color);
if (alt < .75)
glColor4fv(yellow_color);
if (alt < .25)
glColor4fv(red_color);
if ((flash)&&(alt < .10))
glColor4fv(redplus_color);
[player setAlert_flag:ALERT_FLAG_ALT :((alt < .10)&&(player->status == STATUS_IN_FLIGHT))];
hudDrawBarAt( x, y, z1, siz, alt);
}
- (void) drawMissileDisplay:(NSDictionary *) info
{
int x = MISSILES_DISPLAY_X;
int y = MISSILES_DISPLAY_Y;
int sp = MISSILES_DISPLAY_SPACING;
NSSize siz = NSMakeSize( MISSILE_ICON_HEIGHT, MISSILE_ICON_HEIGHT);
if ([info objectForKey:X_KEY])
x = [(NSNumber *)[info objectForKey:X_KEY] intValue];
if ([info objectForKey:Y_KEY])
y = [(NSNumber *)[info objectForKey:Y_KEY] intValue];
if ([info objectForKey:SPACING_KEY])
sp = [(NSNumber *)[info objectForKey:SPACING_KEY] intValue];
if ([info objectForKey:WIDTH_KEY])
siz.width = [(NSNumber *)[info objectForKey:WIDTH_KEY] intValue];
if ([info objectForKey:HEIGHT_KEY])
siz.height = [(NSNumber *)[info objectForKey:HEIGHT_KEY] intValue];
if (![player dial_ident_engaged])
{
int n_mis = [player dial_max_missiles];
int i;
for (i = 0; i < n_mis; i++)
{
if ([player missile_for_station:i])
{
NSString* miss_roles = [[player missile_for_station:i] roles];
NSObject* miss_icon = [[[player universe] descriptions] objectForKey:miss_roles];
if (i == [player active_missile])
{
glColor4fv(yellow_color);
glBegin(GL_POLYGON);
if (miss_icon)
{
hudDrawSpecialIconAt( (NSArray*)miss_icon, x + i * sp + 2, y + 1, z1, NSMakeSize( siz.width + 4, siz.height + 4));
}
else
{
if ([miss_roles hasSuffix:@"MISSILE"])
hudDrawMissileIconAt( x + i * sp + 2, y + 1, z1, NSMakeSize( siz.width + 4, siz.height + 4));
if ([miss_roles hasSuffix:@"MINE"])
hudDrawMineIconAt( x + i * sp + 2, y + 1, z1, NSMakeSize( siz.width + 4, siz.height + 4));
}
glEnd();
switch ([player dial_missile_status])
{
case MISSILE_STATUS_SAFE :
glColor4fv(green_color); break;
case MISSILE_STATUS_ARMED :
glColor4fv(yellow_color); break;
case MISSILE_STATUS_TARGET_LOCKED :
glColor4fv(red_color); break;
}
}
else
{
if ([[player missile_for_station:i] getPrimaryTarget])
glColor4fv(red_color);
else
glColor4fv(green_color);
}
glBegin(GL_POLYGON);
if (miss_icon)
{
hudDrawSpecialIconAt( (NSArray*)miss_icon, x + i * sp, y, z1, siz);
}
else
{
if ([miss_roles hasSuffix:@"MISSILE"])
hudDrawMissileIconAt( x + i * sp, y, z1, siz);
if ([miss_roles hasSuffix:@"MINE"])
hudDrawMineIconAt( x + i * sp, y, z1, siz);
}
glEnd();
if (i != [player active_missile])
{
glColor4fv(green_color);
glBegin(GL_LINE_LOOP);
if (miss_icon)
{
hudDrawSpecialIconAt( (NSArray*)miss_icon, x + i * sp, y, z1, siz);
}
else
{
if ([miss_roles hasSuffix:@"MISSILE"])
hudDrawMissileIconAt( x + i * sp, y, z1, siz);
if ([miss_roles hasSuffix:@"MINE"])
hudDrawMineIconAt( x + i * sp, y, z1, siz);
}
glEnd();
}
}
else
{
glColor4f(0.25, 0.25, 0.25, 0.5);
glBegin(GL_LINE_LOOP);
hudDrawMissileIconAt( x + i * sp, y, z1, siz);
glEnd();
}
}
}
else
{
x -= siz.width;
y -= siz.height * 0.75;
siz.width *= 0.80;
sp *= 0.75;
switch ([player dial_missile_status])
{
case MISSILE_STATUS_SAFE :
glColor4fv(green_color); break;
case MISSILE_STATUS_ARMED :
glColor4fv(yellow_color); break;
case MISSILE_STATUS_TARGET_LOCKED :
glColor4fv(red_color); break;
}
glBegin(GL_QUADS);
glVertex3i( x , y, z1);
glVertex3i( x + siz.width, y, z1);
glVertex3i( x + siz.width, y + siz.height, z1);
glVertex3i( x , y + siz.height, z1);
glEnd();
glColor4f( 0.0, 1.0, 0.0, 1.0);
drawString( [player dial_target_name], x + sp, y, z1, NSMakeSize( siz.width, siz.height));
}
}
- (void) drawTargetReticle:(NSDictionary *) info;
{
// the missile target reticle is an advanced option
// so we need to check for its extra equipment flag first
// if (([info objectForKey:EQUIPMENT_REQUIRED_KEY])&&
// (![player has_extra_equipment:(NSString *)[info objectForKey:EQUIPMENT_REQUIRED_KEY]]))
// return;
//
if ([player dial_missile_status] == MISSILE_STATUS_TARGET_LOCKED)
{
//Entity *target = [player getPrimaryTarget];
hudDrawReticleOnTarget( [player getPrimaryTarget], player, z1);
[self drawDirectionCue:info];
}
}
- (void) drawStatusLight:(NSDictionary *) info
{
GLfloat status_color[4] = { 0.25, 0.25, 0.25, 1.0};
int alert_condition = [player alert_condition];
double flash_alpha = 0.333 * (2.0 + sin([[player universe] getTime] * 2.5 * alert_condition));
int x = STATUS_LIGHT_CENTRE_X;
int y = STATUS_LIGHT_CENTRE_Y;
NSSize siz = NSMakeSize( STATUS_LIGHT_HEIGHT, STATUS_LIGHT_HEIGHT);
if ([info objectForKey:X_KEY])
x = [(NSNumber *)[info objectForKey:X_KEY] intValue];
if ([info objectForKey:Y_KEY])
y = [(NSNumber *)[info objectForKey:Y_KEY] intValue];
if ([info objectForKey:WIDTH_KEY])
siz.width = [(NSNumber *)[info objectForKey:WIDTH_KEY] intValue];
if ([info objectForKey:HEIGHT_KEY])
siz.height = [(NSNumber *)[info objectForKey:HEIGHT_KEY] intValue];
//
switch(alert_condition)
{
case ALERT_CONDITION_RED :
// glColor4fv(red_color);
status_color[0] = red_color[0];
status_color[1] = red_color[1];
status_color[2] = red_color[2];
break;
case ALERT_CONDITION_GREEN :
// glColor4fv(green_color);
status_color[0] = green_color[0];
status_color[1] = green_color[1];
status_color[2] = green_color[2];
break;
case ALERT_CONDITION_YELLOW :
// glColor4fv(yellow_color);
status_color[0] = yellow_color[0];
status_color[1] = yellow_color[1];
status_color[2] = yellow_color[2];
break;
default :
case ALERT_CONDITION_DOCKED :
// glColor4f( 0.25, 0.25, 0.25, 1.0);
break;
}
status_color[3] = flash_alpha;
glColor4fv(status_color);
glBegin(GL_POLYGON);
hudDrawStatusIconAt( x, y, z1, siz);
glEnd();
glColor4f( 0.25, 0.25, 0.25, 1.0);
glBegin(GL_LINE_LOOP);
hudDrawStatusIconAt( x, y, z1, siz);
glEnd();
}
- (void) drawDirectionCue:(NSDictionary *) info
{
// the direction cue is an advanced option
// so we need to check for its extra equipment flag first
if (([info objectForKey:EQUIPMENT_REQUIRED_KEY])&&
(![player has_extra_equipment:(NSString *)[info objectForKey:EQUIPMENT_REQUIRED_KEY]]))
return;
if ([[player universe] displayGUI])
return;
if ([player dial_missile_status] == MISSILE_STATUS_TARGET_LOCKED)
{
GLfloat clear_color[4] = {0.0, 1.0, 0.0, 0.0};
Entity *target = [player getPrimaryTarget];
if (!target)
return;
// draw the direction cue
Matrix rotMatrix;
Vector position = player->position;
gl_matrix_into_matrix([player rotationMatrix], rotMatrix);
//
if ([[player universe] viewDir] != VIEW_DOCKED)
{
GLfloat siz1 = CROSSHAIR_SIZE * (1.0 - ONE_EIGHTH);
GLfloat siz0 = CROSSHAIR_SIZE * ONE_EIGHTH;
GLfloat siz2 = CROSSHAIR_SIZE * (1.0 + ONE_EIGHTH);
Vector rpn = target->position;
// translate the view
rpn.x -= position.x; rpn.y -= position.y; rpn.z -= position.z;
// rotate the view
mult_vector(&rpn, rotMatrix);
switch ([[player universe] viewDir])
{
case VIEW_AFT :
rpn.x = - rpn.x;
break;
case VIEW_PORT :
rpn.x = rpn.z;
break;
case VIEW_STARBOARD :
rpn.x = -rpn.z;
break;
}
rpn.z = 0; // flatten vector
if (rpn.x||rpn.y)
{
rpn = unit_vector(&rpn);
glBegin(GL_LINES);
glColor4fv(clear_color);
glVertex3f( rpn.x * siz1 - rpn.y * siz0, rpn.y * siz1 + rpn.x * siz0, z1);
glColor4fv(green_color);
glVertex3f( rpn.x * siz2, rpn.y * siz2, z1);
glColor4fv(clear_color);
glVertex3f( rpn.x * siz1 + rpn.y * siz0, rpn.y * siz1 - rpn.x * siz0, z1);
glColor4fv(green_color);
glVertex3f( rpn.x * siz2, rpn.y * siz2, z1);
glEnd();
}
}
}
}
- (void) drawClock:(NSDictionary *) info
{
int x = CLOCK_DISPLAY_X;
int y = CLOCK_DISPLAY_Y;
NSSize siz = NSMakeSize( CLOCK_DISPLAY_WIDTH, CLOCK_DISPLAY_HEIGHT);
if ([info objectForKey:X_KEY])
x = [(NSNumber *)[info objectForKey:X_KEY] intValue];
if ([info objectForKey:Y_KEY])
y = [(NSNumber *)[info objectForKey:Y_KEY] intValue];
if ([info objectForKey:WIDTH_KEY])
siz.width = [(NSNumber *)[info objectForKey:WIDTH_KEY] intValue];
if ([info objectForKey:HEIGHT_KEY])
siz.height = [(NSNumber *)[info objectForKey:HEIGHT_KEY] intValue];
glColor4f( 0.0, 1.0, 0.0, 1.0);
drawString( [player dial_clock], x, y, z1, siz);
}
- (void) drawFPSInfoCounter:(NSDictionary *) info
{
Universe* universe = [player universe];
if (![universe displayFPS])
return;
if ((!player)||(!universe))
return;
NSString* positionInfo = [universe expressPosition:player->position inCoordinateSystem:@"pwm"];
int x = FPSINFO_DISPLAY_X;
int y = FPSINFO_DISPLAY_Y;
NSSize siz = NSMakeSize( FPSINFO_DISPLAY_WIDTH, FPSINFO_DISPLAY_HEIGHT);
NSSize siz08 = NSMakeSize( 0.8 * FPSINFO_DISPLAY_WIDTH, 0.8 * FPSINFO_DISPLAY_HEIGHT);
if ([info objectForKey:X_KEY])
x = [(NSNumber *)[info objectForKey:X_KEY] intValue];
if ([info objectForKey:Y_KEY])
y = [(NSNumber *)[info objectForKey:Y_KEY] intValue];
if ([info objectForKey:WIDTH_KEY])
siz.width = [(NSNumber *)[info objectForKey:WIDTH_KEY] intValue];
if ([info objectForKey:HEIGHT_KEY])
siz.height = [(NSNumber *)[info objectForKey:HEIGHT_KEY] intValue];
glColor4f( 0.0, 1.0, 0.0, 1.0);
drawString( [player dial_fpsinfo], x, y, z1, siz);
drawString( [player dial_objinfo], x, y - siz.height, z1, siz);
drawString( positionInfo, x, y - 1.8 * siz.height, z1, siz08);
}
- (void) drawGreenSurround:(NSDictionary *) info
{
int x, y;
NSSize siz;
if ([info objectForKey:X_KEY])
x = [(NSNumber *)[info objectForKey:X_KEY] intValue];
else
return;
if ([info objectForKey:Y_KEY])
y = [(NSNumber *)[info objectForKey:Y_KEY] intValue];
else
return;
if ([info objectForKey:WIDTH_KEY])
siz.width = [(NSNumber *)[info objectForKey:WIDTH_KEY] intValue];
else
return;
if ([info objectForKey:HEIGHT_KEY])
siz.height = [(NSNumber *)[info objectForKey:HEIGHT_KEY] intValue];
else
return;
// draw aft_shield surround
glColor4fv(green_color);
hudDrawSurroundAt( x, y, z1, siz);
}
- (void) drawYellowSurround:(NSDictionary *) info
{
int x, y;
NSSize siz;
if ([info objectForKey:X_KEY])
x = [(NSNumber *)[info objectForKey:X_KEY] intValue];
else
return;
if ([info objectForKey:Y_KEY])
y = [(NSNumber *)[info objectForKey:Y_KEY] intValue];
else
return;
if ([info objectForKey:WIDTH_KEY])
siz.width = [(NSNumber *)[info objectForKey:WIDTH_KEY] intValue];
else
return;
if ([info objectForKey:HEIGHT_KEY])
siz.height = [(NSNumber *)[info objectForKey:HEIGHT_KEY] intValue];
else
return;
// draw aft_shield surround
glColor4fv(yellow_color);
hudDrawSurroundAt( x, y, z1, siz);
}
- (void) drawTrumbles:(NSDictionary *) info
{
}
//---------------------------------------------------------------------//
void hudDrawIndicatorAt(int x, int y, int z, NSSize siz, double amount)
{
if (siz.width > siz.height)
{
int dial_oy = y - siz.height/2;
int position = x + amount * siz.width / 2;
glBegin(GL_QUADS);
glVertex3i( position, dial_oy, z);
glVertex3i( position+2, y, z);
glVertex3i( position, dial_oy+siz.height, z);
glVertex3i( position-2, y, z);
glEnd();
}
else
{
int dial_ox = x - siz.width/2;
int position = y + amount * siz.height / 2;
glBegin(GL_QUADS);
glVertex3i( dial_ox, position, z);
glVertex3i( x, position+2, z);
glVertex3i( dial_ox + siz.width, position, z);
glVertex3i( x, position-2, z);
glEnd();
}
}
void hudDrawBarAt(int x, int y, int z, NSSize siz, double amount)
{
GLfloat dial_ox = x - siz.width/2;
GLfloat dial_oy = y - siz.height/2;
if (fabs(siz.width) > fabs(siz.height))
{
GLfloat position = dial_ox + amount * siz.width;
glBegin(GL_QUADS);
glVertex3f( dial_ox, dial_oy, z);
glVertex3f( position, dial_oy, z);
glVertex3f( position, dial_oy+siz.height, z);
glVertex3f( dial_ox, dial_oy+siz.height, z);
glEnd();
}
else
{
GLfloat position = dial_oy + amount * siz.height;
glBegin(GL_QUADS);
glVertex3f( dial_ox, dial_oy, z);
glVertex3f( dial_ox, position, z);
glVertex3f( dial_ox+siz.width, position, z);
glVertex3f( dial_ox+siz.width, dial_oy, z);
glEnd();
}
}
void hudDrawSurroundAt(int x, int y, int z, NSSize siz)
{
int dial_ox = x - siz.width/2;
int dial_oy = y - siz.height/2;
glBegin(GL_LINE_LOOP);
glVertex3i( dial_ox-2, dial_oy-2, z);
glVertex3i( dial_ox+siz.width+2, dial_oy-2, z);
glVertex3i( dial_ox+siz.width+2, dial_oy+siz.height+2, z);
glVertex3i( dial_ox-2, dial_oy+siz.height+2, z);
glEnd();
}
void hudDrawSpecialIconAt(NSArray* ptsArray, int x, int y, int z, NSSize siz)
{
if (!ptsArray)
return;
int ox = x - siz.width / 2.0;
int oy = y - siz.height / 2.0;
int w = siz.width / 4.0;
int h = siz.height / 4.0;
int i = 0;
int npts = [ptsArray count] & 0xfffe; // make sure it's an even number
while (i < npts)
{
int x = [(NSNumber*)[ptsArray objectAtIndex:i++] intValue];
int y = [(NSNumber*)[ptsArray objectAtIndex:i++] intValue];
glVertex3i( ox + x * w, oy + y * h, z);
}
}
void hudDrawMissileIconAt(int x, int y, int z, NSSize siz)
{
int ox = x - siz.width / 2.0;
int oy = y - siz.height / 2.0;
int w = siz.width / 4.0;
int h = siz.height / 4.0;
glVertex3i( ox, oy + 3 * h, z);
glVertex3i( ox + 2 * w, oy, z);
glVertex3i( ox + w, oy, z);
glVertex3i( ox + w, oy - 2 * h, z);
glVertex3i( ox - w, oy - 2 * h, z);
glVertex3i( ox - w, oy, z);
glVertex3i( ox - 2 * w, oy, z);
}
void hudDrawMineIconAt(int x, int y, int z, NSSize siz)
{
int ox = x - siz.width / 2.0;
int oy = y - siz.height / 2.0;
int w = siz.width / 4.0;
int h = siz.height / 4.0;
glVertex3i( ox, oy + 2 * h, z);
glVertex3i( ox + w, oy + h, z);
glVertex3i( ox + w, oy - h, z);
glVertex3i( ox, oy - 2 * h, z);
glVertex3i( ox - w, oy - h, z);
glVertex3i( ox - w, oy + h, z);
}
void hudDrawStatusIconAt(int x, int y, int z, NSSize siz)
{
int ox = x - siz.width / 2.0;
int oy = y - siz.height / 2.0;
int w = siz.width / 4.0;
int h = siz.height / 4.0;
glVertex3i( ox, oy + h, z);
glVertex3i( ox, oy + 3 * h, z);
glVertex3i( ox + w, oy + 4 * h, z);
glVertex3i( ox + 3 * w, oy + 4 * h, z);
glVertex3i( ox + 4 * w, oy + 3 * h, z);
glVertex3i( ox + 4 * w, oy + h, z);
glVertex3i( ox + 3 * w, oy, z);
glVertex3i( ox + w, oy, z);
}
void hudDrawReticleOnTarget(Entity* target, PlayerEntity* player1, GLfloat z1)
{
//GLfloat z1 = [(MyOpenGLView *)[[player1 universe] gameView] display_z];
ShipEntity* target_ship = (ShipEntity *)target;
NSString* legal_desc = nil;
if ((!target)||(!player1))
return;
switch (target_ship->scan_class)
{
case CLASS_NEUTRAL :
{
int target_legal = [target_ship legal_status];
int legal_i = 0;
if (target_legal > 0)
legal_i = (target_legal <= 50) ? 1 : 2;
legal_desc = [(NSArray *)[[[player1 universe] descriptions] objectForKey:@"legal_status"] objectAtIndex:legal_i];
}
break;
case CLASS_THARGOID :
legal_desc = @"Alien";
break;
case CLASS_POLICE :
legal_desc = @"System Vessel";
break;
case CLASS_MILITARY :
legal_desc = @"Military Vessel";
break;
default :
case CLASS_BUOY :
case CLASS_CARGO :
case CLASS_ROCK :
case CLASS_MISSILE :
case CLASS_NO_DRAW :
case CLASS_STATION :
case CLASS_TARGET :
break;
}
if ([player1 gui_screen] != GUI_SCREEN_MAIN) // don't draw on text screens
return;
if (!target)
return;
gl_matrix back_mat;
Quaternion back_q = player1->q_rotation;
back_q.w = -back_q.w; // invert
Vector p0 = [player1 getViewpointPosition];
Vector p1 = target->position;
p1.x -= p0.x; p1.y -= p0.y; p1.z -= p0.z;
double rdist = sqrt(magnitude2(p1));
double rsize = target->actual_radius;
if (rsize < rdist * ONE_SIXTYFOURTH)
rsize = rdist * ONE_SIXTYFOURTH;
double rs0 = rsize;
//double rs3 = rsize * 0.75;
double rs2 = rsize * 0.50;
//double rs1 = rsize * 0.25;
glPushMatrix();
//
// deal with view directions
Vector view_dir;
switch ([[player1 universe] viewDir])
{
case VIEW_FORWARD :
view_dir.x = 0.0; view_dir.y = 0.0; view_dir.z = -1.0;
break;
case VIEW_AFT :
view_dir.x = 0.0; view_dir.y = 0.0; view_dir.z = 1.0;
quaternion_rotate_about_axis(&back_q,vector_up_from_quaternion(back_q),PI);
break;
case VIEW_PORT :
view_dir.x = 1.0; view_dir.y = 0.0; view_dir.z = 0.0;
quaternion_rotate_about_axis(&back_q,vector_up_from_quaternion(back_q),PI/2.0);
break;
case VIEW_STARBOARD :
view_dir.x = -1.0; view_dir.y = 0.0; view_dir.z = 0.0;
quaternion_rotate_about_axis(&back_q,vector_up_from_quaternion(back_q),-PI/2.0);
break;
case VIEW_DOCKED :
case VIEW_BREAK_PATTERN :
default :
view_dir.x = 0.0; view_dir.y = 0.0; view_dir.z = -1.0;
break;
}
gluLookAt(0.0, 0.0, 0.0, view_dir.x, view_dir.y, view_dir.z, 0.0, 1.0, 0.0);
//
quaternion_into_gl_matrix(back_q, back_mat);
//
// rotate the view
glMultMatrixf([player1 rotationMatrix]);
// translate the view
glTranslatef(p1.x, p1.y, p1.z);
//rotate to face player1
glMultMatrixf(back_mat);
// draw the reticle
glColor4fv(green_color);
glBegin(GL_LINES);
glVertex2f(rs0,rs2); glVertex2f(rs0,rs0);
glVertex2f(rs0,rs0); glVertex2f(rs2,rs0);
glVertex2f(rs0,-rs2); glVertex2f(rs0,-rs0);
glVertex2f(rs0,-rs0); glVertex2f(rs2,-rs0);
glVertex2f(-rs0,rs2); glVertex2f(-rs0,rs0);
glVertex2f(-rs0,rs0); glVertex2f(-rs2,rs0);
glVertex2f(-rs0,-rs2); glVertex2f(-rs0,-rs0);
glVertex2f(-rs0,-rs0); glVertex2f(-rs2,-rs0);
// NSLog(@"DEBUG rs0 %.3f %.3f",rs0, rs2);
glEnd();
// add text for reticle here
float range = sqrt(target->zero_distance)/1000;
NSSize textsize = NSMakeSize( rdist * ONE_SIXTYFOURTH, rdist * ONE_SIXTYFOURTH);
float line_height = rdist * ONE_SIXTYFOURTH;
NSString* info1 = [target_ship identFromShip: player1];
NSString* info2 = (legal_desc == nil)? [NSString stringWithFormat:@"%0.3f km", range] : [NSString stringWithFormat:@"%0.3f km (%@)", range, legal_desc];
// no need to set color - tis green already!
drawString( info1, rs0, 0.5 * rs2, 0, textsize);
drawString( info2, rs0, 0.5 * rs2 - line_height, 0, textsize);
glPopMatrix();
}
double drawCharacterQuad(int chr, double x, double y, double z, NSSize siz)
{
if ((chr < 0) || (chr > 127))
return 0;
double texture_x = ONE_SIXTEENTH * (chr & 0x0f);
double texture_y = ONE_EIGHTH * (chr >> 4); // divide by 16 fast
glTexCoord2f( texture_x, texture_y + ONE_EIGHTH);
glVertex3f( x, y, z);
glTexCoord2f( texture_x + ONE_SIXTEENTH, texture_y + ONE_EIGHTH);
glVertex3f( x + siz.width, y, z);
glTexCoord2f( texture_x + ONE_SIXTEENTH, texture_y);
glVertex3f( x + siz.width, y + siz.height, z);
glTexCoord2f( texture_x, texture_y);
glVertex3f( x, y + siz.height, z);
return siz.width * 0.13 * char_widths[chr];
}
void drawString(NSString *text, double x, double y, double z, NSSize siz)
{
int i;
double cx = x;
// NSLog(@"DEBUG drawing string (%@) at %.1f, %.1f, %.1f (%.1f x %.1f)", text, x, y, z, siz.width, siz.height);
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glBindTexture(GL_TEXTURE_2D, ascii_texture_name);
// glColor4f( 0.0, 1.0, 0.0, 1.0);
glBegin(GL_QUADS);
for (i = 0; i < [text length]; i++)
{
int ch = (int)[text characterAtIndex:i];
ch = ch & 0x7f;
cx += drawCharacterQuad( ch, cx, y, z, siz);
}
glEnd();
glDisable(GL_TEXTURE_2D);
}
NSRect rectForString(NSString *text, double x, double y, NSSize siz)
{
int i;
double w = 0;
for (i = 0; i < [text length]; i++)
{
int ch = (int)[text characterAtIndex:i];
ch = ch & 0x7f;
w += siz.width * 0.13 * char_widths[ch];
}
return NSMakeRect( x, y, w, siz.height);
}
void drawScannerGrid( double x, double y, double z, NSSize siz, int v_dir, GLfloat thickness)
{
GLfloat ww = 0.5 * siz.width;
GLfloat w1 = 0.125 * siz.width;
GLfloat w2 = 0.250 * siz.width;
// GLfloat w3 = 0.375 * siz.width;
GLfloat hh = 0.5 * siz.height;
GLfloat h1 = 0.125 * siz.height;
GLfloat h2 = 0.250 * siz.height;
GLfloat h3 = 0.375 * siz.height;
// glColor4f( 1.0, 0.0, 0.0, alpha);
glLineWidth(2.0 * thickness);
drawOval( x, y, z, siz, 4);
glLineWidth(thickness);
glBegin(GL_LINES);
glVertex3f(x, y - hh, z); glVertex3f(x, y + hh, z);
glVertex3f(x - ww, y, z); glVertex3f(x + ww, y, z);
glVertex3f(x - w1, y - h1, z); glVertex3f(x + w1, y - h1, z);
glVertex3f(x - w1, y - h2, z); glVertex3f(x + w1, y - h2, z);
glVertex3f(x - w1, y - h3, z); glVertex3f(x + w1, y - h3, z);
glVertex3f(x - w1, y + h1, z); glVertex3f(x + w1, y + h1, z);
glVertex3f(x - w1, y + h2, z); glVertex3f(x + w1, y + h2, z);
glVertex3f(x - w1, y + h3, z); glVertex3f(x + w1, y + h3, z);
switch (v_dir)
{
case VIEW_BREAK_PATTERN :
case VIEW_DOCKED :
case VIEW_FORWARD :
case VIEW_NONE :
glVertex3f( x, y, z); glVertex3f(x - w2, y + hh, z);
glVertex3f( x, y, z); glVertex3f(x + w2, y + hh, z);
break;
case VIEW_AFT :
glVertex3f( x, y, z); glVertex3f(x - w2, y - hh, z);
glVertex3f( x, y, z); glVertex3f(x + w2, y - hh, z);
break;
case VIEW_PORT :
glVertex3f( x, y, z); glVertex3f(x - ww, y + h2, z);
glVertex3f( x, y, z); glVertex3f(x - ww, y - h2, z);
break;
case VIEW_STARBOARD :
glVertex3f( x, y, z); glVertex3f(x + ww, y + h2, z);
glVertex3f( x, y, z); glVertex3f(x + ww, y - h2, z);
break;
}
glEnd();
}
void drawOval( double x, double y, double z, NSSize siz, int step)
{
int i;
GLfloat ww = 0.5 * siz.width;
GLfloat hh = 0.5 * siz.height;
glBegin(GL_LINE_LOOP);
for (i = 0; i < 360; i += step)
glVertex3f(x + ww * sin_value[i], y + hh * sin_value[(i + 90) % 360], z);
// glVertex3f(x, y + hh, z);
glEnd();
return;
}
void drawFilledOval( double x, double y, double z, NSSize siz, int step)
{
int i;
GLfloat ww = 0.5 * siz.width;
GLfloat hh = 0.5 * siz.height;
glBegin(GL_TRIANGLE_FAN);
glVertex3f( x, y, z);
for (i = 0; i < 360; i += step)
glVertex3f(x + ww * sin_value[i], y + hh * sin_value[(i + 90) % 360], z);
glVertex3f(x, y + hh, z);
glEnd();
return;
}
void drawSpecialOval( double x, double y, double z, NSSize siz, int step, GLfloat* color4v)
{
int i;
GLfloat ww = 0.5 * siz.width;
GLfloat hh = 0.5 * siz.height;
glEnable(GL_LINE_SMOOTH);
glBegin(GL_LINE_LOOP);
for (i = 0; i < 360; i += step)
{
glColor4f( color4v[0], color4v[1], color4v[2], fabs(sin_value[i] * color4v[3]));
glVertex3f(x + ww * sin_value[i], y + hh * sin_value[(i + 90) % 360], z);
}
glEnd();
return;
}
- (void) setLine_width:(GLfloat) value
{
line_width = value;
}
- (GLfloat) line_width
{
return line_width;
}
@end