/* Bridge Window Drawing Functions: void BridgeDrawTitle(CDisplay *display) void BridgeDrawHelp(CDisplay *display) void BridgeDrawClearVS(CDisplay *display) void BridgeDrawPlayerStats(CDisplay *display, int object_num) void BridgeDrawSubjectStats(CDisplay *display, int object_num) void BridgeDrawVSObject( CDisplay *display, Window w, xsw_object_struct *camera_obj_ptr, xsw_object_struct *camera_locked_obj_ptr, xsw_object_struct *obj_ptr, int screen_x, int screen_y ) void BridgeDrawVSObjects(CDisplay *display) void BridgeDrawMessages(CDisplay *display) void BridgeDrawStatusBar(CDisplay *display) --- */ #include #include #include "../include/unvmath.h" #include "net.h" #include "swterm.h" #define RADTODEG(r) ((r) * 180 / PI) /* * Redraws the bridge title. */ void BridgeDrawTitle(CDisplay *display) { int x, y; unsigned int width, height; Window w; if(display == NULL) return; w = display->root_win; width = CWRootWidth(display); height = CWRootHeight(display); CWClearArea(display, w, 0, 0, width, 1); if(net_parms.connection_state != CON_STATE_NOT_CONNECTED) { x = ((int)width / 2) - (strlen(net_parms.address) / 2); y = 0; CWDrawStringPosition( display, w, x, y, net_parms.address ); } return; } /* * Draws help keys. */ void BridgeDrawHelp(CDisplay *display) { int x, y; Window w; if(display == NULL) return; w = display->root_win; x = 1; y = 2; CWDrawStringPosition( display, w, x, y, "F9 = Connect. F10 = Disconnect." ); y += 1; CWDrawStringPosition( display, w, x, y, "F11 = Refresh. F12 = Connect last." ); y += 1; CWDrawStringPosition( display, w, x, y, "e = Server command. x = Exit." ); y += 1; CWDrawStringPosition( display, w, x, y, "a = Auto network tunning on/off. [ ] = Adjust network interval." ); y += 1; CWDrawStringPosition( display, w, x, y, "Cursor up down = Throttle. Cursor left right = Heading." ); y += 1; CWDrawStringPosition( display, w, x, y, "- + = Viewscreen zoom. , . = Select weapon." ); y += 1; CWDrawStringPosition( display, w, x, y, "w = Weapons offline/online. space = Fire/use weapon." ); y += 1; CWDrawStringPosition( display, w, x, y, "tab = Lock on `next' object u = Unlock weapons." ); y += 1; CWDrawStringPosition( display, w, x, y, "k = Change com channel. ' = Send message." ); y += 1; CWDrawStringPosition( display, w, x, y, "h = Send hail. s = Raise/lower shields." ); y += 1; CWDrawStringPosition( display, w, x, y, "f = Change shield frequency. y = Change weapon frequency." ); y += 1; CWDrawStringPosition( display, w, x, y, "i = Set intercept course. z = Cloak." ); y += 1; CWDrawStringPosition( display, w, x, y, "l = Vector lights on/off. s = Strobe lights on/off." ); y += 2; CWDrawStringPosition( display, w, x, y, "Press F1 to exit this screen." ); return; } /* * Clears the bridge window viewscreen area. */ void BridgeDrawClearVS(CDisplay *display) { unsigned int width, height; Window w; if(display == NULL) return; w = display->root_win; width = CWRootWidth(display); height = CWRootHeight(display); CWClearArea( display, w, 0, 1, width, (int)height - 6 ); return; } /* * Draws player stats. * * Does not clear or refresh the bridge window, the bridge window * is assumed to have been already cleared. */ void BridgeDrawPlayerStats(CDisplay *display, int object_num) { int x, y, xc, yc, hc, wc, len; unsigned int width, height; xsw_object_struct *obj_ptr; int sel_wep_num; xsw_weapons_struct *wep_ptr; Window w; char text[XSW_OBJ_NAME_MAX + 256]; if(display == NULL) return; w = display->root_win; width = CWRootWidth(display); height = CWRootHeight(display); wc = 40; hc = (int)height - 5; if(DBIsObjectGarbage(object_num)) return; else obj_ptr = xsw_object[object_num]; /* Begin draw. */ /* Player name. */ x = 1; y = 1; strncpy(text, DBGetFormalNameStr(object_num), XSW_OBJ_NAME_MAX); text[XSW_OBJ_NAME_MAX - 1] = '\0'; CWDrawStringPosition( display, w, x, y, text ); /* Com channel. */ y += 2; sprintf(text, "Com Channel: %.2lf Weapon Frequency %.2lf", (double)obj_ptr->com_channel / 100, local_control.weapon_freq ); CWDrawStringPosition( display, w, x, y, text ); /* Hit points. */ y += 1; sprintf(text, "HP: %.2lf(%.2lf) %.0lf%% %s", obj_ptr->hp, obj_ptr->hp_max, (double)((obj_ptr->hp_max > 0) ? (double)obj_ptr->hp / (double)obj_ptr->hp_max : 0 ) * 100, ((obj_ptr->damage_control == DMGCTL_STATE_ON) ? "[dmgctl]" : "") ); CWDrawStringPosition( display, w, x, y, text ); /* Core power. */ y += 1; sprintf(text, "CP: %.2lf(%.2lf)", obj_ptr->power, obj_ptr->power_max ); CWDrawStringPosition( display, w, x, y, text ); /* Shield state and freq. */ y += 1; if((obj_ptr->shield_state == SHIELD_STATE_UP) && (obj_ptr->power_max > 0) ) { sprintf(text, "SH: %.0lf%% @ %.2lf", (obj_ptr->power / obj_ptr->power_max) * 100, obj_ptr->shield_frequency ); CWDrawStringPosition( display, w, x, y, text ); } /* Cloak state. */ y += 1; sprintf(text, "V: %.0lf%% %s", DBGetObjectVisibilityPtr(obj_ptr) * 100, ((obj_ptr->cloak_state == CLOAK_STATE_UP) ? "*cloaked*" : "") ); CWDrawStringPosition( display, w, x, y, text ); /* Engine and antimatter. */ y += 1; sprintf(text, "Eng: %s AM: %.2lf(%.2lf)", ((obj_ptr->engine_state == ENGINE_STATE_ON) ? "on" : "off"), obj_ptr->antimatter, obj_ptr->antimatter_max ); CWDrawStringPosition( display, w, x, y, text ); /* Intercept. */ y += 1; if(!DBIsObjectGarbage(obj_ptr->intercepting_object)) { sprintf(text, "I: %s", DBGetFormalNameStr(obj_ptr->intercepting_object) ); CWDrawStringPosition( display, w, x, y, text ); } /* Heading, velocity and position. */ y += 2; sprintf(text, "HD: %.2lf' S: %.4lf", RADTODEG(obj_ptr->heading), obj_ptr->velocity ); CWDrawStringPosition( display, w, x, y, text ); y += 1; sprintf(text, "Sect: %ld %ld %ld", obj_ptr->sect_x, obj_ptr->sect_y, obj_ptr->sect_z ); CWDrawStringPosition( display, w, x, y, text ); y += 1; sprintf(text, "Pos: %.2lf %.2lf %.2lf", obj_ptr->x, obj_ptr->y, obj_ptr->z ); CWDrawStringPosition( display, w, x, y, text ); /* Controller positions. */ /* y += 2; strcpy(text, "<--------->"); len = strlen(text) - 2; xc = (((gctl[0].turn + 1) / 2) * len) + 1; if(xc < 1) xc = 1; if(xc >= (len + 1)) xc = (len + 1) - 1; text[xc] = '|'; CWDrawStringPosition( display, w, x, y, text ); */ y += 2; strcpy(text, "[----+----]"); len = strlen(text) - 2; yc = (((gctl[0].throttle + 1) / 2) * len) + 1; if(yc < 1) yc = 1; if(yc >= (len + 1)) yc = (len + 1) - 1; text[yc] = '|'; CWDrawStringPosition( display, w, x, y, text ); sprintf(text, "%.0lf%%", gctl[0].throttle * 100); CWDrawStringPosition( display, w, x + 14, y, text ); /* Selected weapon. */ y += 2; while(local_control.weapons_online) { sel_wep_num = obj_ptr->selected_weapon; if((sel_wep_num < 0) || (sel_wep_num >= obj_ptr->total_weapons) ) break; wep_ptr = obj_ptr->weapons[sel_wep_num]; if(wep_ptr == NULL) break; switch(wep_ptr->emission_type) { case WEPEMISSION_PROJECTILE: sprintf(text, "%i. %s: %i(%i)", sel_wep_num, wep_ptr->name, wep_ptr->amount, wep_ptr->max ); break; default: sprintf(text, "%i. %s: %.2lf%%", sel_wep_num, wep_ptr->name, ((obj_ptr->power_max > 0) ? obj_ptr->power / obj_ptr->power_max * 100 : 0 ) ); break; } CWDrawStringPosition( display, w, x, y, text ); break; } /* Viewscreen zoom (lower left). */ x = 1; y = (int)height - 6; sprintf(text, "Scanner Range: %.2lf (%.0lf%%)\n", obj_ptr->scanner_range * bridge_win.vs_zoom, bridge_win.vs_zoom * 100 ); CWDrawStringPosition( display, w, x, y, text ); return; } /* * Draws subject stats. * * Does not clear or refresh the bridge window, the bridge window * is assumed to have been already cleared. */ void BridgeDrawSubjectStats(CDisplay *display, int object_num) { int x, y, xc, yc, hc, wc, len; unsigned int width, height; double bearing, distance; char *units_str; xsw_object_struct *obj_ptr, *player_obj_ptr; Window w; char text[XSW_OBJ_NAME_MAX + 256]; if(display == NULL) return; w = display->root_win; width = CWRootWidth(display); height = CWRootHeight(display); wc = 40; hc = (int)height - 5; if(DBIsObjectGarbage(object_num)) return; else obj_ptr = xsw_object[object_num]; player_obj_ptr = net_parms.player_obj_ptr;; if(player_obj_ptr == NULL) return; /* Begin draw. */ /* Subject name. */ y = 1; strncpy(text, DBGetFormalNameStr(object_num), XSW_OBJ_NAME_MAX); text[XSW_OBJ_NAME_MAX - 1] = '\0'; x = (int)width - strlen(text) - 2; CWDrawStringPosition( display, w, x, y, text ); /* Bearing and distance. */ y += 2; if(Mu3DInSameSectorPtr(obj_ptr, player_obj_ptr)) { bearing = MuCoordinateDeltaVector( obj_ptr->x - player_obj_ptr->x, obj_ptr->y - player_obj_ptr->y ); distance = Mu3DDistance( obj_ptr->x - player_obj_ptr->x, obj_ptr->y - player_obj_ptr->y, obj_ptr->z - player_obj_ptr->z ); units_str = "reals"; } else { bearing = MuCoordinateDeltaVector( obj_ptr->sect_x - player_obj_ptr->sect_x, obj_ptr->sect_y - player_obj_ptr->sect_y ); distance = Mu3DDistance( obj_ptr->sect_x - player_obj_ptr->sect_x, obj_ptr->sect_y - player_obj_ptr->sect_y, obj_ptr->sect_z - player_obj_ptr->sect_z ); units_str = "sectors"; } sprintf(text, "BRG: %.2lf' D: %.2lf %s", (double)RADTODEG(bearing), distance, units_str ); x = (int)width - strlen(text) - 2; CWDrawStringPosition( display, w, x, y, text ); /* Hit points. */ y += 2; sprintf(text, "HP: %.2lf(%.2lf) %.0lf%%", obj_ptr->hp, obj_ptr->hp_max, (double)((obj_ptr->hp_max > 0) ? (double)obj_ptr->hp / (double)obj_ptr->hp_max : 0 ) * 100 ); x = (int)width - strlen(text) - 2; CWDrawStringPosition( display, w, x, y, text ); /* Core power. */ y += 1; sprintf(text, "CP: %.2lf(%.2lf)", obj_ptr->power, obj_ptr->power_max ); x = (int)width - strlen(text) - 2; CWDrawStringPosition( display, w, x, y, text ); /* Shield state and freq. */ y += 1; if((obj_ptr->shield_state == SHIELD_STATE_UP) && (obj_ptr->power_max > 0) ) { sprintf(text, "SH: %.0lf%%", (obj_ptr->power / obj_ptr->power_max) * 100 ); x = (int)width - strlen(text) - 2; CWDrawStringPosition( display, w, x, y, text ); } /* Sector and position. */ y += 1; sprintf(text, "Sect: %ld %ld %ld", obj_ptr->sect_x, obj_ptr->sect_y, obj_ptr->sect_z ); x = (int)width - strlen(text) - 2; CWDrawStringPosition( display, w, x, y, text ); y += 1; sprintf(text, "Pos: %.2lf %.2lf %.2lf", obj_ptr->x, obj_ptr->y, obj_ptr->z ); x = (int)width - strlen(text) - 2; CWDrawStringPosition( display, w, x, y, text ); return; } /* * Procedure to draw the given object (assumed valid). */ void BridgeDrawVSObject( CDisplay *display, Window w, xsw_object_struct *camera_obj_ptr, xsw_object_struct *camera_locked_obj_ptr, xsw_object_struct *obj_ptr, int screen_x, int screen_y ) { char tmp_char; int i, x, y; double visibility; /* Do not draw if visiblity is too low. */ visibility = DBGetObjectVisibilityPtr(obj_ptr); if(visibility < 0.10) return; /* Choose character to represent object based on type. */ switch(obj_ptr->type) { case XSW_OBJ_TYPE_AREA: tmp_char = 'A'; break; case XSW_OBJ_TYPE_HOME: tmp_char = 'O'; break; case XSW_OBJ_TYPE_PLAYER: case XSW_OBJ_TYPE_CONTROLLED: tmp_char = '^'; break; case XSW_OBJ_TYPE_WEAPON: case XSW_OBJ_TYPE_STREAMWEAPON: case XSW_OBJ_TYPE_SPHEREWEAPON: tmp_char = '*'; break; default: tmp_char = '+'; break; } if(camera_locked_obj_ptr == obj_ptr) tmp_char = '#'; /* Draw character representing object. */ CWDrawCharacter( display, w, screen_x, screen_y, tmp_char ); /* Draw marking indicating heading. */ i = (int)((obj_ptr->heading / (2 * PI)) * 8); switch(i) { case 1: x = 1; y = -1; tmp_char = '/'; break; case 2: x = 1; y = 0; tmp_char = '-'; break; case 3: x = 1; y = 1; tmp_char = '\\'; break; case 4: x = 0; y = 1; tmp_char = '|'; break; case 5: x = -1; y = 1; tmp_char = '/'; break; case 6: x = -1; y = 0; tmp_char = '-'; break; case 7: x = -1; y = -1; tmp_char = '\\'; break; default: x = 0; y = -1; tmp_char = '|'; break; } if((obj_ptr->type == XSW_OBJ_TYPE_PLAYER) || (obj_ptr->type == XSW_OBJ_TYPE_CONTROLLED) ) CWDrawCharacter( display, w, screen_x + x, screen_y + y, tmp_char ); return; } /* * Procedure to draw each object in range. */ void BridgeDrawVSObjects(CDisplay *display) { int i, camera_obj_num; double x, y, d; double camera_scanner_range; double real_to_screen_coeff; int x_trans, y_trans, longest_dimension; unsigned int width, height; xsw_object_struct **ptr, *obj_ptr, *camera_obj_ptr, *camera_locked_obj_ptr; Window w; if(display == NULL) return; w = display->root_win; /* Get referances to camera object. */ camera_obj_num = net_parms.player_obj_num; camera_obj_ptr = net_parms.player_obj_ptr; /* Don't draw if camera object is not available. */ if(camera_obj_ptr == NULL) return; /* Set screen translation offset. */ x_trans = 0; y_trans = 1; /* Get screen size. */ width = CWRootWidth(display); height = (int)CWRootHeight(display) - 6; /* Get longest screen size dimension. */ if(width > height) longest_dimension = width; else longest_dimension = height; /* Get scanner range of camera object. */ if(camera_obj_ptr->loc_type == XSW_LOC_TYPE_NEBULA) camera_scanner_range = camera_obj_ptr->scanner_range * VISIBILITY_NEBULA; else camera_scanner_range = camera_obj_ptr->scanner_range; /* Get object that camera is locked on to. */ if(DBIsObjectGarbage(camera_obj_ptr->locked_on)) camera_locked_obj_ptr = NULL; else camera_locked_obj_ptr = xsw_object[camera_obj_ptr->locked_on]; /* Calculate real units to screen units coefficient. */ d = camera_scanner_range * bridge_win.vs_zoom; if(d <= 0) d = 0.01; real_to_screen_coeff = (longest_dimension / 2) / d; /* Begin drawing objects in the in range objects list. */ for(i = 0, ptr = inrange_xsw_object; i < total_inrange_objects; i++, ptr++ ) { obj_ptr = *ptr; if(obj_ptr == NULL) continue; if(obj_ptr->type <= XSW_OBJ_TYPE_GARBAGE) continue; if(!Mu3DInSectorPtr(obj_ptr, camera_obj_ptr->sect_x, camera_obj_ptr->sect_y, camera_obj_ptr->sect_z )) continue; x = (obj_ptr->x - camera_obj_ptr->x) * real_to_screen_coeff; y = (obj_ptr->y - camera_obj_ptr->y) * real_to_screen_coeff; x += (int)((int)width / 2); y += (int)((int)height / 2); /* Flip y value. */ y = (int)height - y; /* Off screen check. */ if((x < 1) || (y < 1) || (x >= ((int)width - 1)) || (y >= ((int)height - 1)) ) continue; BridgeDrawVSObject( display, w, camera_obj_ptr, camera_locked_obj_ptr, obj_ptr, x + x_trans, y + y_trans ); } return; } /* * Redraws messag box. */ void BridgeDrawMessages(CDisplay *display) { int i, n, x, y, xc, yc, wc, hc, len; char *strptr; char tmp_char; unsigned int width, height; Window w; int lines_visable = 3; /* Lines visable. */ if(display == NULL) return; w = display->root_win; width = CWRootWidth(display); height = CWRootHeight(display); x = 1; y = (int)height - 1 - lines_visable; wc = x + (int)width - 2; hc = y + lines_visable; /* Set up i to be the starting message index. */ i = bridge_win.message_scroll_pos; if(i < 0) i = 0; for(yc = y; yc < hc; yc++, i++) { if(i >= bridge_win.total_messages) break; if(bridge_win.message[i] == NULL) continue; strptr = bridge_win.message[i]->message; if(strptr == NULL) len = 0; else len = strlen(strptr); for(xc = x, n = 0; xc < wc; xc++, n++) { if(n < len) tmp_char = strptr[n]; else tmp_char = ' '; CWDrawCharacter( display, w, xc, yc, tmp_char ); } } /* CWSync(display, 0); */ return; } /* * Redraws the status bar on the bridge window. */ void BridgeDrawStatusBar(CDisplay *display) { int i, len, xc, yc, wc; char *connect_state_str; char text[256]; char tmp_char; unsigned int width, height; if(display == NULL) return; width = CWRootWidth(display); height = CWRootHeight(display); xc = 1; yc = (int)height - 1; wc = xc + (int)width - 2; switch(net_parms.connection_state) { case CON_STATE_CONNECTED: connect_state_str = "====="; break; case CON_STATE_NEGOTIATING: connect_state_str = "-> <-"; break; default: connect_state_str = "<- ->"; break; } if(net_parms.connection_state > CON_STATE_NOT_CONNECTED) sprintf( text, "[%s] Int(%s): %ld ms SX: %i RX: %i Lapse: %ld ms", connect_state_str, ((auto_interval_tune.state) ? "on" : "off"), net_parms.net_int, (int)(loadstat.sx_ilast * (double)(1000 / (double)auto_interval_tune.interval)), (int)(loadstat.rx_ilast * (double)(1000 / (double)auto_interval_tune.interval)), lapsed_millitime ); else sprintf( text, "[%s] Int(%s): %ld ms Lapse: %ld ms", connect_state_str, ((auto_interval_tune.state) ? "on" : "off"), net_parms.net_int, lapsed_millitime ); len = strlen(text); i = 0; while(xc < wc) { if(i < len) tmp_char = text[i]; else tmp_char = ' '; CWDrawCharacter( display, display->root_win, xc, yc, tmp_char ); xc++; i++; } /* CWSync(display, 0); */ return; }